一、什么是 requestAnimationFrame?
requestAnimationFrame常用來執行動畫效果。
-
屏幕刷新頻率:屏幕每秒出現圖像的次數。普通筆記本為60Hz
-
動畫原理:計算機每16.7ms刷新一次,由於人眼的視覺停留,所以看起來是流暢的移動。
-
setTimeout:通過設定間隔時間來不斷改變圖像位置,達到動畫效果。但是容易出現卡頓、抖動的現象;原因是:1、settimeout任務被放入異步隊列,只有當主線程任務執行完后才會執行隊列中的任務,因此實際執行時間總是比設定時間要晚;2、settimeout的固定時間間隔不一定與屏幕刷新時間相同,會引起丟幀。
-
requestAnimationFrame:優勢:由系統決定回調函數的執行時機。60Hz的刷新頻率,那么每次刷新的間隔中會執行一次回調函數,不會引起丟幀,不會卡頓。
-
CPU節能:使用setTimeout實現的動畫,當頁面被隱藏或最小化時,setTimeout 仍然在后台執行動畫任務,由於此時頁面處於不可見或不可用狀態,刷新動畫是沒有意義的,完全是浪費CPU資源。而requestAnimationFrame則完全不同,當頁面處理未激活的狀態下,該頁面的屏幕刷新任務也會被系統暫停,因此跟着系統步伐走的requestAnimationFrame也會停止渲染,當頁面被激活時,動畫就從上次停留的地方繼續執行,有效節省了CPU開銷。
- 函數節流:在高頻率事件(resize,scroll等)中,為了防止在一個刷新間隔內發生多次函數執行,使用requestAnimationFrame可保證每個刷新間隔內,函數只被執行一次,這樣既能保證流暢性,也能更好的節省函數執行的開銷。
三、通過案例了解requestAnimationFrame的執行順序
for(let i =0;i<5;i++) {
requestAnimationFram(()=> console.log(i));
}
輸出 結果:0 1 2 3 4
解析:requestAnimationFrame雖然是異步函數,但是由於i是用let定義的,每一次循環都會生成一個塊級作用域,保存當前的值。
如果換成var i = 0,則輸出結果為 4 4 4 4