寫在前面
- 說到優化是個很大話題,估計寫本書也說不完。本文只針對前端動畫的優化來淺述。
- 本文概念性的東西比較多(如:reflow、repaint),理解概念是前提。其中重排和重繪是兩個重要概念(由於它們是致使卡頓的重要緣由,其中重排的成本比重繪高不少)。
重排
- 概念:即reflow,當咱們在某個元素上執行動畫時,瀏覽器須要每一幀都檢測是否有元素受到影響,並調整他們的大小,位置,一般這種調整都是聯動的,咱們稱爲reflow。
- 觸發重排的相關屬性:
- 盒子模型相關屬性會觸發重佈局
- width
- height
- padding
- margin
- display
- border-width
- border
- min-height
- 定位屬性及浮動也會觸發重佈局
- top
- bottom
- left
- right
- position
- float
- 改變節點內部文字結構也會觸發重佈局
- text-align
- overflow-y
- font-weight
- overflow
- font-family
- line-height
- vertival-align
- white-space
- font-size
重繪
- 概念:即repaint,動畫執行時,瀏覽器還須要監聽元素的外觀變化,一般是背景色,陰影,邊框等可視元素,並進行重繪,咱們稱爲repaint。
- 觸發重繪的相關屬性:
- color
- border-style
- border-radius
- visibility
- text-decoration
- background
- background-image
- background-position
- background-repeat
- background-size
- outline-color
- outline
- outline-style
- outline-width
- box-shadow
瀏覽器是如何渲染DOM的
- 獲取DOM後分割爲多個圖層
- 對每一個圖層的節點計算樣式結果(Recalculate style--樣式重計算)
- 爲每一個節點生成圖形和位置(Layout--迴流和重佈局)
- 將每一個節點繪製填充到圖層位圖中(Paint Setup和Paint--重繪)
- 圖層做爲紋理上傳至GPU
- 符合多個圖層到頁面上生成最終屏幕圖像(Composite Layers–圖層重組)
建立新的渲染層
建立新的渲染層,執行動畫時,只須要GPU按照現有的位圖,按照相應的變換在獨立的渲染層中輸出,而後再合併輸出。這個過程並不須要主線程CPU的參與,這就是優化的核心點。css
建立新的渲染層的狀況:前端
- 當一個元素位於HTML文檔的最外層(元素)
- 當一個元素position不爲initial,而且擁有一個z-index值(不爲auto)
- 當一個元素被設置了opacity,transforms, filters, css-regions, paged media等屬性。
- (固然還會有其餘狀況,具體可參考下面的參考連接)
JS動畫和CSS3動畫的比較
- js動畫:優勢是咱們能隨時控制開始,暫停,中止。缺點是沒辦法像css這樣優化,由於js動畫是在主線程上跑的,容易卡頓丟幀。
- css3動畫:優勢是瀏覽器能夠對動畫進行優化。它必要時能夠建立圖層,而後在主線程以外運行。缺點是缺少強大的控制能力。
結論
- 咱們應該盡力避免使用會觸發重佈局和重繪的屬性,以避免失幀。最好提早申明動畫,這樣能讓瀏覽器提早對動畫進行優化。
- 如今用來作動畫的最好屬性是以下幾個:opacity、translate、rotate、scale,儘可能避免left/padding/background-position等。
- 若是須要JS執行動畫,使用requestAnimationFrame,或者Velocity,避免使用jQuery動畫,setTimeout,setInterval。
- 儘量的爲產生動畫的元素使用fixed或absolute的position。
- 使用3D硬件加速提高動畫性能時,最好給元素增長一個z-index屬性,人爲干擾複合層的排序,能夠有效減小chrome建立沒必要要的複合層,提高渲染性能,移動端優化效果尤其明顯。
- 然而並非全部瀏覽器默認都會開啓GPU渲染,因此一般會用translate3d,translateZ,或者是opacity < 1等來強制開啓。
參考連接css3