基本概念
-
60fps
60fps是指GPU渲染畫面的頻率。Hz代表顯示器刷新屏幕的頻率。
HZ <==> fps
60fps是一個最理想的狀態,在日常對頁面性能的測試中,60fps也是一個重要的指標,the closer the better!
低于30fps將會明顯卡頓! -
瀏覽器渲染原理
- Main Thread 主線程
- 主線程主要運行js,計算樣式,將位圖交給繪制線程繪制
- Compositor Thread 繪制線程
- 繪制線程主要通過GPU將位圖繪制到屏幕上
- Main Thread 主線程
如果長時間的執行 JS 會阻塞主線程,頁面就會出現各種的卡頓。而繪制線程會盡量的去響應用戶的交互,頁面發生變化時,繪制線程會以每秒60幀(因為每秒60幀是最適合人眼的交互,小于30就會明顯感覺到卡頓)的間隔不斷重繪頁面。
瀏覽器接收到頁面文檔后,會將文檔中的標記語言解析為DOM樹。DOM樹和CSS結合后形成瀏覽器構建頁面的渲染樹
div {
height: 100px;
transition: height 1s linear;
}
div:hover {
height: 200px;
}
因為每一幀的變化瀏覽器都在進行布局、繪制、把新的位圖交給 GPU 內存(這恰好是我們上面提到的GPU的短板)
div {
transform: scale(0.5);
transition: transform 1s linear;
}
div:hover {
transform: scale(1.0);
}
transform 屬性不會改變自己和他周圍元素的布局,他會對元素的整體產生影響。
why?
由于JavaScript運行時需要耗費時間,而JavaScript又是單線程的,所以如果一個定時器如果比較耗時的話,是會阻塞下一個定時器的執行。所以即使你這里設置了1000 / 60每秒60幀的幀率,在不同的瀏覽器平臺的差異也會導致實際上你的沒有60fps的幀率。
Best Pratics
tips1
硬件加速,強制使用GPU渲染元素。
創建一個新的復合圖層,圖層在GPU中 transform是不會觸發 repaint 的,這一點非常類似3D繪圖功能。
- 3D 或者 CSS transform
- <video>和 <canvas>標簽
- CSS filters opacity
- 元素覆蓋時,比如使用了 z-index屬性
tips2
NO JQuery
Javascript 動畫很快,而 jQuery 動畫很慢。盡管 jQuery 異常強大,但是它的設計目標并不是一個高效的動畫引擎。
- jQuery 不能避免 layout thrashing (有人喜歡將其翻譯為“布局顛簸”,會導致多余relayout/reflow),因為它的代碼不僅僅用于動畫,它還用于很多其他場景。
- jQuery的內存消耗較大,經常會觸發垃圾回收。而垃圾回收觸發時很容易讓動畫卡住。
- jQuery使用了setInterval而不是 reqeustAnimationFrame(RAF),因為 RAF 會在窗口失去焦點時停止觸發,這會導致jQuery的bug。(目前jQuery已經使用了RAF)
內存:如果GPU加載了大量的紋理,那么很容易就會發生內容問題,這一點在移動端瀏覽器上尤為明顯,所以,一定要牢記不要讓頁面的每個元素都使用硬件加速。