requestAnimationFrame
來看一個小例子
<body>
<div id="box"></div>
</body>
<script type="text/javascript">
var box = document.getElementById("box");
function run(){
box.innerHTML = new Date().getTime();
setTimeout(run, 16);
}
setTimeout(run, 16);
</script>
這個例子當中, 我們通過setTimeout讓run函數(shù)每秒執(zhí)行60次.
想要按照瀏覽器的刷新頻率來執(zhí)行函數(shù), 其實不需要這么麻煩.
另外, 如果瀏覽器的刷新頻率不是60, 甚至低于60, 那么我們的動畫就可能出現(xiàn)掉幀情況.
啥叫掉幀?
一般情況下, 瀏覽器的幀率跟屏幕幀率一致, 基本都是60, 也就是16ms左右會刷新一次
如果, 你的定時器時間過短, 就會出現(xiàn)上圖的現(xiàn)象.
在瀏覽器兩次刷新畫面中間, 定時器函數(shù)執(zhí)行了2次
而這2次操作都是在內(nèi)存完成的動作, 瀏覽器只有刷新才能看到效果
也就是說, 用戶本該看到的兩幀畫面, 丟了一幀.
畫面會顯得不流暢, 甚至一定程度上出現(xiàn) "卡頓"
這就是俗稱的掉幀現(xiàn)象.
解決這個問題, 直觀的辦法就是把延遲時間寫的長一點.
這里我們引入更簡單的方法
<body>
<div id="box"></div>
</body>
<script type="text/javascript">
var box = document.getElementById("box");
function run(){
box.innerHTML = new Date().getTime();
requestAnimationFrame(run);
}
requestAnimationFrame(run);
</script>
requestAnimationFrame 類似于 setTimeout, 只不過它不需要設定延遲時間
時間會根據(jù)瀏覽器的幀率自動調(diào)節(jié). 也就是在瀏覽器下一次刷新前調(diào)用這個函數(shù)
每次刷新前, 調(diào)用1次函數(shù), 確保函數(shù)的執(zhí)行頻率跟刷新頻率一致.
由于是每一幀畫面執(zhí)行1次函數(shù), 因此requestAnimationFrame又叫 "幀動畫" 函數(shù),它會帶來兩個好處:
1. 避免了計算 1000/60 ≈ 16, 瀏覽器會自動處理
2. 當標簽頁運行在后臺的時候, 它會自動暫停運行以節(jié)省CPU資源
經(jīng)過我的實際測試, chrome\firefox\360\ie11, 幀率都是60
也就是說, 除非你把延遲時間 設定的 小于 16, 才有可能在理論上出現(xiàn)掉幀
又由于setTimeout是異步任務, 所以實際當中的時間間隔往往是大于實際值的
因此, 掉幀的情況是很難發(fā)生的.
所以, requestAnimationFrame方法的主要好處來源于第2條.
更多關于web前端培訓的問題,歡迎咨詢千鋒教育在線名師,如果想要了解我們的師資、課程、項目實操的話可以點擊咨詢課程顧問,獲取試聽資格來試聽我們的課程,在線零距離接觸千鋒教育大咖名師,讓你輕松從入門到精通。