天天看點

☀️什麼是重繪和重排? 如何去避免?

☀️什麼是重繪和重排? 如何去避免?

前言

面試官:既然你剛剛提到了重繪和重排,那就說一說吧。

我:。。。💥

我們首先來回顧一下

渲染流水線

的流程:

☀️什麼是重繪和重排? 如何去避免?

回流

首先介紹

回流

回流

也叫

重排

觸發條件

簡單來說,就是當我們對 DOM 結構的修改引發

DOM 幾何尺寸變化

的時候,會發生

回流

的過程。比如以下情況

  1. 一個 DOM 元素的幾何屬性變化,常見的幾何屬性有

    width

    height

    padding

    margin

    left

    top

    border

    等等, 這個很好了解。
  2. 使 DOM 節點發生

    增減

    或者

    移動

  3. 讀寫

    offset

    族、

    scroll

    族和

    client

    族屬性的時候,浏覽器為了擷取這些值,需要進行回流操作。
  4. 調用

    window.getComputedStyle

    方法。

回流過程

依照上面的渲染流水線,觸發回流的時候,如果 DOM 結構發生改變,則重新渲染 DOM 樹,然後将後面的流程(包括主線程之外的任務)全部走一遍。

☀️什麼是重繪和重排? 如何去避免?

相當于将解析和合成的過程重新又走了一遍,開銷是非常大的。

重繪

觸發條件

當 DOM 的修改導緻了

樣式的變化

,并且

沒有影響幾何屬性的時候

,會導緻

重繪

(

repaint

)。

重繪過程

由于沒有導緻 DOM 幾何屬性的變化,是以元素的位置資訊不需要更新,進而省去布局的過程。流程如下:

☀️什麼是重繪和重排? 如何去避免?

跳過了

生成布局樹

建圖層樹

的階段,直接生成繪制清單,然後繼續進行分塊、生成位圖等後面一系列操作。

是以說:

重繪不一定導緻回流,但回流一定發生了重繪

合成

這是我們可能不太熟悉的一種情況,是

直接合成

。比如利用 CSS3 的

transform

opacity

filter

這些屬性就可以實作合成的效果,也就是大家常說的GPU加速。

GPU加速的原因

在合成的情況下,會直接跳過布局和繪制流程,直接進入

非主線程

處理的部分,即直接交給

合成線程

處理。交給它處理有兩大好處:

  1. 能夠充分發揮

    GPU

    的優勢。合成線程生成位圖的過程中會調用線程池,并在其中使用

    GPU

    進行加速生成,而GPU 是擅長處理位圖資料的。
  2. 沒有占用主線程的資源,即使主線程卡住了,效果依然能夠流暢地展示。

總結

知道上面的原理之後,對于開發過程有什麼指導意義呢?

  1. 避免頻繁使用 style,而是采用修改

    class

    的方式。
  2. 使用

    createDocumentFragment

    進行批量的 DOM 操作。
  3. 對于 resize、scroll 等進行防抖/節流處理。
  4. 添加 will-change: tranform ,讓渲染引擎為其單獨實作一個圖層,當這些變換發生時,僅僅隻是利用合成線程去處理這些變換,而不牽扯到主線程,大大提高渲染效率。當然這個變化不限于

    tranform

    , 任何可以實作合成效果的 CSS 屬性都能用

    will-change

    來聲明。

繼續閱讀