css優化之重排與重繪

瀏覽器的渲染機制

主要分爲以下幾個步驟:

  • 解析HTML(HTML Parser)
  • 構建DOM樹(DOM Tree)
  • 渲染樹構建(Render Tree)
  • 繪製渲染樹(Painting)

瀏覽器取回代碼後,首先會構造DOM樹,根據HTML標籤,構造DOM樹。

之後會解析CSS樣式,解析的順序是瀏覽器的樣式 -> 用戶自定義的樣式 -> 頁面的link標籤等引進來的樣式 -> 寫在style標籤裏面的內聯樣式

 

 

 

 

 

 

 

 

 

 

 

 

網頁生成的時候,至少會渲染一次。用戶訪問的過程中,還會不斷重新渲染。

重新渲染,就需要重新生成佈局和重新繪製。前者叫做重排(reflow),後者叫做重繪(repaint)。

需要注意的是,重繪不一定需要重排,重排必然導致重繪。

爲了提高網頁性能,就要降低"重排"和"重繪"的頻率和成本,儘量少觸發重新渲染。

 

慎重選擇高消耗的樣式

什麼 CSS 屬性是高消耗的?就是那些繪製前需要瀏覽器進行大量計算的屬性。

  • box-shadows

  • border-radius

  • transparency

  • transforms

  • CSS filters(性能殺手)

 

什麼是reflow

瀏覽器爲了重新渲染部分或整個頁面,重新計算頁面元素位置和幾何結構的進程叫做reflow.

通俗點說就是當開發人員定義好了樣式後(也包括瀏覽器的默認樣式),瀏覽器根據這些來計算並根據結果將元素放到它應該出現的位置上,這個過程叫做reflow.

由於reflow是一種瀏覽器中的用戶攔截操作,所以我們瞭解如何減少reflow次數,及DOM的層級,css效率對refolw次數的影響是十分有必要的。

reflow(迴流)是導致DOM腳本執行效率低的關鍵因素之一,頁面上任何一個節點觸發了reflow,會導致它的子節點及祖先節點重新渲染。

<body>
  <div class="hello">
    <h4>hello</h4>
    <p><strong>Name:</strong>BDing</p>
    <h5>male</h5>
    <ol>
      <li>coding</li>
      <li>loving</li>
    </ol>
  </div>
</body>

當p節點上發生reflow時,hello和body也會重新渲染,甚至h5和ol都會收到影響。

 

什麼時候會導致reflow發生呢?

  • 改變窗口大小
  • 改變文字大小
  • 添加/刪除樣式表
  • 內容的改變,(用戶在輸入框中寫入內容也會)
  • 激活僞類,如:hover
  • 操作class屬性
  • 腳本操作DOM
  • 計算offsetWidth和offsetHeight
  • 設置style屬性
常見的重排元素   
width height padding margin
display border-width border top
position font-size float text-align
overflow-y font-weight overflow left
font-family line-height vertical-align right
clear white-space bottom min-height

 

 

 

 

 

 

 

怎麼減少 Reflow

  1. 不要一條一條地修改 DOM 的樣式,預先定義好 class,然後修改 DOM 的 className

  2. 把 DOM 離線後修改,比如:先把 DOM 給 display:none (有一次 Reflow),然後你修改100次,然後再把它顯示出來

  3. 不要把 DOM 結點的屬性值放在一個循環裏當成循環裏的變量

  4. 儘可能不要修改影響範圍比較大的 DOM

  5. 爲動畫的元素使用絕對定位 absolute / fixed

  6. 不要使用 table 佈局,可能很小的一個小改動會造成整個 table 的重新佈局

 

什麼是repaint

repaint是在一個元素的外觀被改變,但沒有改變佈局的情況下發生的,如改變了visibility、outline、background等。當repaint發生時,瀏覽器會驗證DOM樹上所有其他節點的visibility屬性。·

通俗來說,就是當各種盒子的位置、大小以及其他屬性,例如顏色、字體都確定下來後,瀏覽器便把這些元素都按照各自的特性繪製一遍,於是頁面的內容出現了,這個過程叫做repaint

 

避免過分重繪(Repaints)

當元素改變的時候,將不會影響元素在頁面當中的位置(比如 background-color, border-color, visibility),瀏覽器僅僅會應用新的樣式重繪此元素,此過程稱爲 Repaint

 

常見的重繪元素   
color border-style visibility background
text-decoration background-image background-position background-repeat
outline-color outline outline-style border-radius
outline-width box-shadow background-size

 

 

 

 

 

 

優化動畫

css3 動畫是優化的重中之重。除了做到上面兩點,減少 Reflow 和 Repaints 之外,還需要注意以下方面。

啓用 GPU 硬件加速

GPU(Graphics Processing Unit) 是圖像處理器GPU 硬件加速是指應用 GPU 的圖形性能對瀏覽器中的一些圖形操作交給 GPU 來完成,因爲 GPU專門爲處理圖形而設計,所以它在速度和能耗上更有效率。
GPU 加速可以不僅應用於3D,而且也可以應用於2D。這裏, GPU 加速通常包括以下幾個部分:Canvas2D佈局合成(Layout Compositing), CSS3轉換(transitions)CSS3 3D變換(transforms)WebGL視頻(video)

/*
 * 根據上面的結論
 * 將 2d transform 換成 3d
 * 就可以強制開啓 GPU 加速
 * 提高動畫性能
 */
div {
  transform: translate(10px, 10px);
}
div {
  transform: translate3d(10px, 10px, 0);
}

 

需要注意的是,開啓硬件加速相應的也會有額外的開銷,參見這篇文章 CSS 硬件加速的好與壞·

參考以下文章:

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