會引起Reflow和Repaint的操作有哪些?

王铁柱6發表於2024-11-27

在前端開發中,有很多操作會引起 Reflow(迴流)和 Repaint(重繪)。理解這些操作有助於開發者最佳化頁面效能,減少卡頓,提升使用者體驗。

Reflow (迴流) 定義: 當瀏覽器需要重新計算元素的幾何尺寸和位置時,就會發生迴流。迴流的成本比重繪高得多,因為它會影響到整個文件的佈局,甚至觸發子元素甚至父元素以及後續元素的迴流。

Repaint (重繪) 定義: 當元素的外觀發生改變,但沒有改變佈局(例如,改變顏色、背景色、字型樣式等)時,就會發生重繪。

引起 Reflow 和 Repaint 的操作:

以下操作通常會引起迴流和重繪,其中一些操作的影響更大:

  • 改變 DOM 元素的幾何屬性: 例如寬度、高度、padding、margin、border、display、position 等。
  • 新增或刪除 DOM 元素: 對 DOM 樹的修改會影響佈局,從而導致迴流。
  • 移動 DOM 元素: 使用 offsetLeftoffsetTopoffsetWidthoffsetHeight 等屬性獲取元素的位置和尺寸資訊,這些操作會強制瀏覽器進行迴流以獲取最新的值。 儘量避免在迴圈中讀取這些屬性。
  • 改變 CSS 樣式: 很多樣式的改變都會導致迴流,例如字型大小、字型樣式、文字內容等。
  • 改變瀏覽器視窗大小 (resize): 視窗大小的改變會強制所有元素重新計算佈局。
  • 滾動頁面 (scroll): 滾動頁面會觸發部分元素的重新佈局和繪製。
  • :hover 偽類樣式: :hover 樣式的應用可能會導致迴流和重繪,尤其是在 hover 樣式影響佈局的情況下。
  • 計算 offsetWidthoffsetHeight: 訪問這些屬性會強制瀏覽器進行迴流以返回正確的值。
  • 設定 style 屬性: 直接操作元素的 style 屬性會觸發迴流和重繪。

減少 Reflow 和 Repaint 的方法:

  • 批次修改 DOM: 使用 DocumentFragment 建立一個文件片段,在片段中進行 DOM 操作,最後一次性新增到文件中,減少迴流次數。
  • 使用 CSS3 屬性: 例如 transform 和 opacity,這些屬性的改變不會觸發迴流,只會觸發重繪,效能更好。
  • 避免頻繁讀取會觸發迴流的屬性: 例如 offsetLeftoffsetTopoffsetWidthoffsetHeight 等。快取這些值,避免重複讀取。
  • 使用 class 操作樣式: 避免直接操作 style 屬性,使用 class 來修改樣式,瀏覽器可以批次處理樣式更改。
  • 離線渲染: 使用 Canvas 或 SVG 進行繪製,可以避免瀏覽器迴流和重繪。
  • 使用 will-change 屬性: will-change 屬性可以告知瀏覽器哪些元素可能會發生變化,瀏覽器可以提前進行最佳化。 但是要謹慎使用,過度使用反而會降低效能。
  • Debounce 和 Throttle: 對於 resize 和 scroll 等頻繁觸發的事件,可以使用 Debounce 和 Throttle 技術來減少事件處理的頻率,從而減少迴流和重繪。

透過理解 Reflow 和 Repaint 的原理,並採取相應的最佳化措施,可以顯著提升網頁的效能和使用者體驗。

相關文章