瀏覽器的回流(重排)與重繪

圖片來自網絡

我們經常說到瀏覽器的性能問題,其實與瀏覽器性能息息相關的一點就是瀏覽器如何渲染我們的網頁,這個時候我們就會涉及到一個概念,那就是瀏覽器的回流(重排,以下統稱回流,Reflow)與重繪(Repaint)。

回流

對回流這個詞,我的理解是回爐重造,即對于整個網頁重新渲染一遍。那我們可以思考一下,從性能角度來講,如果我們來寫瀏覽器的代碼,一定是再必須要重新渲染網頁的時候再重新渲染,那就推出一個問題,什么時候瀏覽器必須要重新渲染網頁?

其實必定是當網頁的元素坐標發生變化的時候,這里我們可以理解為有很多人在排隊,大家僅僅的依靠在一起,那什么時候大家需要都挪動下位置呢?我覺得要么就是一個人或者幾個人突然變胖了/瘦了,那大家如果想要繼續依靠在一起,就得都動一動;或者其中一個人或者幾個人挪動了一下自己的位置,他勢必也會擠著其他人去動一動位置。這種重新渲染全部或部分文檔的動作我們就叫做回流,因為大家都需要挪動下位置,也就導致我們這個網頁需要回爐重造了。

所以會導致回流的操作(包括但不限于):

  • 頁面首次渲染

  • 瀏覽器窗口大小發生改變

  • 元素尺寸或位置發生改變

  • 元素內容變化(文字數量或圖片大小等等)

  • 元素字體大小變化

  • 添加或者刪除可見DOM元素

  • 激活CSS偽類(例如::hover

重繪

還是拿排隊舉例,當隊伍中的一個人需要換一件衣服,比如他從穿黃衣服換成穿紅色的衣服,這個時候只要這一個人換件衣服就行了,對其他人并沒有影響,這種情況我們就叫做重繪。瀏覽器只需要對該元素進行重新繪制即可。

所以會導致回流的操作(包括但不限于):

  • 修改color/background-color/visibility

由上述可見,其實回流對瀏覽器性能的消耗是高于重繪的,而且回流的操作一定會伴隨著重繪,重繪卻不一定伴隨回流。那現代瀏覽器其實對這塊是有進行優化處理的,如果我們的隊伍總是需要變換位置,我們就統一來一次大排隊。

那么我們在平時的工作中,如果針對于回流和重繪寫出性能更好地代碼呢?有以下幾點可以注意的:

CSS
  • 避免使用table布局。

  • 盡可能在DOM樹的最末端改變class

  • 避免設置多層內聯樣式。

  • 將動畫效果應用到position屬性為absolutefixed的元素上。

  • 避免使用CSS表達式(例如:calc())。

JavaScript
  • 避免頻繁操作樣式,最好一次性重寫style屬性,或者將樣式列表定義為class并一次性更改class屬性。

  • 避免頻繁操作DOM,創建一個documentFragment,在它上面應用所有DOM操作,最后再把它添加到文檔中。

  • 也可以先為元素設置display: none,操作結束后再把它顯示出來。因為在display屬性為none的元素上進行的DOM操作不會引發回流和重繪。

  • 避免頻繁讀取會引發回流/重繪的屬性,如果確實需要多次使用,就用一個變量緩存起來。

  • 對具有復雜動畫的元素使用絕對定位,使它脫離文檔流,否則會引起父元素及后續元素頻繁回流。

參考 瀏覽器的回流與重繪 (Reflow & Repaint)


博客地址 北落師門

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容