RequestAnimationFrame知多少?
在web應用中,實現動畫效果的方法比較多,例如js中可以通過定時器setTimeout來實現;CSS3可以通過transition和animation來實現;html5中通過Canvas來實現。除此之外,html5還提供一個專門用于請求動畫的API,即requestAnimationFrame(請求動畫幀)。
?屏幕繪制頻率:
即圖像在屏幕上更新的速度,即屏幕上圖像每秒出現的次數,一般這個頻率是60HZ,所以一幅畫面的刷新頻率大約是16.7ms。大多數瀏覽器都會對重繪操作加以限制,不超過顯示器的重繪頻率,以為即使超過那個頻率用戶的體驗也不會提升。
?
CSS動畫原理
動畫的本質就是讓人眼看到圖像被繪制而引起變化的視覺效果,這個變化要連貫、平滑的方式進行過渡。因為電腦屏幕以每秒60次的頻率繪制,繪制頻率很高所以感覺不到它在繪制。
js中使用setTimeout實現動畫在某些低端機上會出現卡頓、抖動的現象,主要有兩個原因:
(1)setTimeout的執行時間并不是確定的。在js中setTimeout任務被放入異步隊列中,只有當主線程上的任務執行完之后,才會去檢查異步任務是否需要開始執行,所以setTimeout的執行時間一般比設定的晚一些。
(2)刷新頻率受屏幕分辨率和屏幕尺寸影響,不同設備的屏幕繪制頻率可能會不同,而setTimeout只能設置一個固定的時間間隔,這個時間不一定和屏幕的刷新時間相同。
以上兩種情況都會導致setTimeout的執行步調和屏幕的刷新步調不一致,從而引起丟幀現象。所以為什么步調不一致會出現丟幀呢?
首先setTimeout的執行只是在內存中對元素的屬性進行改變,這個變化必須要等到屏幕下次繪制時才會被更新到屏幕上。如果步調不一致會導致中間某些幀的操作直接被跨越過去,而直接更新下一幀。
假設屏幕每隔16.7ms刷新一次,而setTimeout 每隔10ms設置圖像向左移動1px, 就會出現如下繪制過程(表格)
從上面的繪制過程中可以看出,屏幕沒有更新 left=2px 的那一幀畫面,元素直接從left=1px 的位置跳到了 left=3px 的的位置,這就是丟幀現象,這種現象就會引起動畫卡頓。
?
requestAnimationFrame(rAF)
與setTimeout相比,rAF的最大優勢是由系統來決定回調函數的執行時機。具體來講就是,系統每次繪制之前都會主動調用rAF中的回調函數。所以rAF的執行頻率是跟著系統的繪制頻率走的,他能保證回調函數在屏幕每一次的繪制間隔中只被執行一次,這樣就不會出現丟幀現象和動畫卡頓。
?
requestAnimationFrame()方法接收一個參數,即在繪制屏幕前調用的一個函數,這個函數負責改變下一次繪制的DOM樣式。
function updateProcess(){var div=document.getElementById('status');div.style.width=(parseInt(div.style.width)+5)+'px';if(div.style.width!="300px"){window.requestAnimationFrame(updateProcess);} } window.requestAnimationFrame(updateProcess);rAF還有兩個優勢:
(1)CPU節能:使用setTimeout實現的動畫,當頁面被隱藏或最小化時,setTimeout仍然在后臺執行動畫任務,由于此時頁面處于不可見或不可用的狀態,刷新動畫是沒有意義的,還浪費CPU資源。而rAF不同,當頁面處于未激活的狀態下,該頁面的屏幕繪制任務也被系統暫停,因此跟著系統步伐的rAF也停止渲染,當頁面被激活時,動畫就從上次停留的地方繼續執行,有效節約了CPU開銷。
(2)函數節流:在高頻率事件(resize、scroll等)這種,為了防止在一個刷新間隔內發生多次函數執行,使用rAF可保證每個繪制間隔內函數只被執行一次,這樣既能保證流暢性,也能更好的節省函數執行的開銷。
?
轉載于:https://www.cnblogs.com/xiaoan0705/p/11212149.html
總結
以上是生活随笔為你收集整理的RequestAnimationFrame知多少?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Luogu2791 幼儿园篮球题【斯特林
- 下一篇: 常数优化的一些技巧