根據W3C性能小組的介紹,超過50ms的任務就是長任務。
圖片來自使用 RAIL 模型評估性能
根據上圖我們可以知道,當延遲超過100ms,用戶就會察覺到輕微的延遲。
所以為了避免這種情況,我們可以使用兩種方案,一種是Web Worker,另一種是時間切片(Time Slicing)。
Web Worker
我們都知道,JS是單線程,所以當我們在運行長任務時,容易造成頁面假死的狀態,雖然我們可以將任務放在任務隊列中,通過異步的方式執行,但這並不能改變JS的本質。
所以為了改變這種現狀,whatwg推出了Web Workers。
具體的語法不會進行說明,有興趣的童鞋可以查看MDN Web Worker。
我們可以看看使用了Web Worker之後的優化效果:
<code>const testWorker = new Worker('./worker.js')
setTimeout(_ => {
testWorker.postMessage({})
testWorker.onmessage = function (ev) {
console.log(ev.data)
}
}, 5000)
// worker.js
self.onmessage = function () {
const start = performance.now()
while (performance.now() - start < 1000) {}
postMessage('done!')
}/<code>
時間切片(Time Slicing)
時間切片是一項使用得比較廣的技術方案,它的本質就是將長任務分割為一個個執行時間很短的任務,然後再一個個地執行。
這個概念在我們日常的性能優化上是非常有用的。
例如當我們需要在頁面中一次性插入一個長列表時(當然,通常這種情況,我們會使用分頁去做)。
如果利用時間分片的概念來實現這個功能,我們可以使用requestAnimationFrame+DocumentFragment
關於這兩個API,我同樣不會做詳細的介紹,有興趣的可以查看MDN requestAnimationFrame跟MDN DocumentFragment。
這裡有兩個DEMO,大家可以對比下流暢程度:
未使用時間分片:
<code>
/<code>
使用時間分片:
<code>
/<code>
沒有做太多的測評,但是從用戶視覺上的感受來看就是,第一種方案,我就是想刷新都要打好幾個轉,往下滑的時候也有白屏的現象。
除了上述的生成DOM的方案,我們同樣可以利用Web Api requestIdleCallback 以及ES6 API Generator]來實現。
同樣不會做太多的介紹,詳細規則可以看MDN requestIdleCallback以及MDN Generator。
具體實現如下:
<code>
/<code>
web-performance
Measure Performance with the RAIL Model
讓你的網頁更絲滑
「前端進階」高性能渲染十萬條數據(時間分片)
以上內容都是我自己的一些感想,分享出來歡迎大家指正,順便求一波關注,有問題有想法的夥伴可以評論或者私信我哦~
閱讀更多 即將禿頭的Java程序員 的文章