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


前言:

  在了解回流與重繪之前,我們先來了解下瀏覽器的渲染機制:

  1. 瀏覽器采用的是流式布局模型(Flow Based Layout)

  2. 瀏覽器會把CSS解析成CSSOM Tree,把HTML解析成 DOM Tree,把這兩個合並成 Render Tree

  3. 有了Render Tree 我們就知道了所有節點的位置和樣式,瀏覽器就開始計算他們在頁面中的位置,然后開始繪制

  4. 由於瀏覽器是流式布局,對於Render Tree的計算通常只需要遍歷一遍就可以完成。但是table及其內部的元素除外,他們可能要計算多次,需要花費等同的元素3倍的時間,這也是不推薦使用table的原因。

回流(Reflow)

當Render Tree 中的部分或全部元素的尺寸,結構或者處罰某些屬性時,瀏覽器會重新計算並渲染頁面,稱為回流。此時瀏覽器需要重新進行計算,計算后還需要重新頁面布局,因此是較重的操作。

會導致回流的操作有:

  • 頁面初次渲染
  • 瀏覽器窗口發生改變
  • 元素尺寸,位置,內容發生變化
  • 元素字體大小變化
  • 添加或者刪除的可見dom元素
  • 激活CSS偽類,例如 :hover
  • 查詢某些屬性或調用某些方法

一些常用的會導致回流的屬性或方法

  • clientWidth, clientHeight, clientTop, clientLeft
  • offsetWidth, offsetHeight, offsetTop, offsetLeft
  • scrollWidth, scrollHeight, scrollTop, scrollLeft
  • scrollIntorView(), scrollInToViewIfNeeded()
  • getComputedStyle()
  • getBoundingClientRect()
  • scrollTop
  • ...

重繪(Repaint)

當元素的樣式改變不影響布局時(例如:color, background-color, visibility等),瀏覽器將使用重繪對元素進行更新,此時由於只需要對UI層面重新繪制,因此損耗較少

 

回流一定會導致重繪,但是重繪不一定會導致回流

 

如何避免:

CSS

  • 避免使用table布局
  • 盡可能在DOM樹的最末端改變class
  • 避免設置多層內聯樣式
  • 避免CSS表達式

JavaScript

  • 避免頻繁的操作樣式,最好一次性寫好style屬性,或者將樣式定義為calss,並一次性更改class屬性
  • 避免頻繁操作DOM,創建一個 documentFragment ,這這個上面應用所有的DOM操作,最后再把它添加到文檔中
  • 也可以先設置為display:none; 操作結束后再把它顯示出來,因為在dispkay屬性為none的元素上進行DOM操作不會引起回流和重繪
  • 避免頻繁讀取引發回流、重繪的屬性,如果要多次使用,建議先把它緩存起來
  • 對具有復雜動畫的元素使用絕對定位,使它脫離文檔流,否則會引起父元素及后續元素頻繁回流。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM