前端性能優化3:重繪與迴流

本文目錄:

  • 1.css性能是否會javascript的執行
  • 2.觸發頁面重佈局的屬性
  • 3.只觸發重繪的屬性
  • 4.新建DOM的過程
  • 5.如何將DOM元素變成新的獨立圖層
  • 6.chrome頁面分析工具
  • 7.實戰優化點總結

1.css性能是否會javascript的執行

確實會。
css代碼的執行會阻塞頁面的渲染,同時js的執行也會執行頁面的渲染,當我們在js寫一個死循環的時候,會頁面渲染卡住。
但是瀏覽器有一個進程是負責Javascript解析,另外一個線程是負責UI渲染的
明明在不同的線程上,但是爲什麼會沒法同時進行呢?
其實這是因爲瀏覽器的執行原理。瀏覽器規定:UI線程和JavaScript線程是互斥的(因爲js的進行往往依賴DOM,如果js的執行的同時伴隨着DOM的改變,則會造成執行代碼的邏輯混亂)
頻繁的去改變css,觸發迴流與重繪,也就是UI線程頻繁進行工作,必然會影響js的執行進程。

什麼是迴流
當render tree中的一部分(或全部)因爲元素的規模尺寸,佈局,隱藏等改變而需要重新構建。這就稱爲迴流(reflow)
當頁面佈局和幾何屬性改變時就需要回流

什麼是重繪
當render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,比如background-color。則就叫稱爲重繪。

迴流必將引起重繪,而重繪不一定會引起迴流

2.觸發頁面重佈局的屬性

  • 盒子模型相關屬性會觸發重佈局
    width,height,padding,margin,display,border-width,border,min-height
  • 定位屬性及浮動也會觸發重佈局
    top,bottom,left,right,position,float,clear
  • 改變節點內部文字結構也會觸發重佈局
    text-align,overflow-y,font-weight,overflow,font-family,line-height,vertival-align,white-space,font-size

3.只觸發重繪的屬性

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

4.新建DOM的過程

  1. 獲取DOM後分割爲多個圖層
  2. 對每個圖層的節點計算樣式結果(Recalculate style--樣式重計算)
  3. 爲每個節點生成圖形和位置(Layout--迴流和重佈局)
  4. 將每個節點繪製填充到圖層位圖中(Paint Setup和Paint--重繪)
  5. 圖層作爲紋理上傳至GPU
  6. 符合多個圖層到頁面上生成最終屏幕圖像(Composite Layers--圖層重組)

將頻繁重繪迴流的DOM元素單獨作爲一個獨立的圖層, 那麼這個DOM元素的重繪和迴流的影響只會在這個圖層之中。
但是要注意:頁面渲染的時候進行圖層合併是非常消耗性能的,所以是否需要建立更多的圖層需要根據實際情況來定。

5.如何將DOM元素變成新的獨立圖層

這涉及到相關的css屬性,我們以chrome爲例:
Chrome創建圖層的條件

  • 3D或透視變換(perspective transform)CSS屬性
  • 使用加速視頻解碼的<video>節點
  • 擁有3D(WebGL)上下文或加速的2D上下文的<canvas>節點
  • 混合插件(如Flash)
  • 對自己的opacity做CSS動畫或使用一個動畫webkit變換的元素
  • 擁有加速CSS過濾器的元素
  • 元素有一個包含複合層的後代節點(一個元素擁有一個子元素,該子元素在自己的層裏)
  • 元素有一個z-index較低且包含一個複合層的兄弟元素(換句話說就是該元素在複合層上面渲染)
  • gif格式的圖片

6.chrome頁面分析工具

Performance


方框1點擊開始開始頁面運行過程的錄製,在運行彈窗中點擊stop就可以停止
chrome會在這個界面詳細展示錄製過程中瀏覽器運行的所有細節。

點擊方框區域,可以自由選擇想要詳細查看和分析的時間段

layers界面可以詳細展示當前頁面的所有圖層

勾選Paint flashing,接下來正常進行頁面操作,瀏覽器會中當前盡心重繪的元素進行標綠。


7.實戰優化點總結

    1. 用translate替代top改變(translate不會觸發迴流)
    1. 用opacity替代visibility
    1. 不要一條一條地修改 DOM 的樣式,預先定義好 class,然後修改 DOM 的 className
    1. 把 DOM 離線後修改,比如:先把 DOM 給 display:none (有一次 Reflow),然後你修改100次,然後再把它顯示出來
    1. 不要把 DOM 結點的屬性值放在一個循環裏當成循環裏的變量,比如我們要去獲取offsetHeight或者offsetWidth,而瀏覽器獲取這兩個屬性都必須去觸發迴流,把這兩個屬性值放在循環中獲取,會導致頁面不斷的迴流
    1. 不要使用 table 佈局,可能很小的一個小改動會造成整個 table 的重新佈局
    1. 動畫實現的速度的選擇,過快的動畫頻率會導致頁面一直處於迴流狀態,因爲導致js執行阻塞
    1. 對於動畫新建圖層,給對應的標籤加上will-change:transform或者transform:translateZ(0)樣式都可以將對應的元素變成一個獨立的圖層
    1. 啓用 GPU 硬件加速(translate3D就是應用GPU的運算能力),常規情況對元素添加上transform:translateZ(0)或者transform:translate3d(0,0,0)都可以讓該元素的渲染啓動GPU加速,但是使用GPU也有缺點:
      1.使用GPU可以節省CPU的渲染消耗,但是需要從CPU進行數據傳輸,這個傳輸的損耗和CPU自身直接進行計算的損耗需要進行平衡取捨
      2.啓動GPU會在頁面新建圖層,而圖層的建立與合併也都是需要消耗CPU的性能的

寫在最後:
上述所講的方法,尤其是新建圖層與啓用GPU,在項目完成之後一定要進行數據化嚴密測量再確定是否使用相關的優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章