前言
在網頁效能和瀏覽器渲染方面,重繪和迴流是兩個非常重要的概念。他們描述了瀏覽器在頁面發生變化時如何重新渲染內容,理解他們有助於編寫高效的網頁程式碼。
1. 迴流(Reflow)
迴流又叫重排,是指當頁面中的元素尺寸、佈局、或幾何屬性發生變化時,瀏覽器需要重新計算元素的位置和尺寸,並重新生成佈局。這一過程會影響頁面中所有與變化元素相關的部分,可能導致整個頁面重新佈局。
什麼會觸發迴流?
新增或刪除 DOM 元素。比如透過 JavaScript 動態插入、刪除元素。
改變元素的幾何屬性。包括寬度、高度、邊距、內邊距、邊框寬度等的變化。
修改瀏覽器視窗大小。當瀏覽器視窗大小改變時,需要重新計算佈局。
字型大小的變化。例如透過 CSS 動態更改
font-size
。滾動操作。當頁面滾動時,瀏覽器需要重新計算可見區域的佈局。
CSS 屬性的變化。一些會影響佈局的屬性(例如
display
、position
、width
、height
等)發生改變時。
迴流的影響
迴流是一個非常消耗效能的操作,尤其是在頁面元素複雜且層級較深的情況下,因為瀏覽器需要重新計算佈局,並重新繪製所有受影響的元素。如果迴流操作頻繁,可能會導致頁面效能問題,比如卡頓、操作延遲等。
2. 重繪(Repaint)
重繪指的是頁面元素的外觀(例如顏色、背景、邊框樣式等)發生變化時,瀏覽器重新繪製這些元素的過程。重繪不會影響頁面的佈局,只會重新繪製已經存在的元素。
什麼會觸發重繪?
顏色變化。例如透過 CSS 修改
color
、background-color
。字型顏色和陰影的變化。
透明度變化。如使用 CSS 的
opacity
屬性。邊框樣式變化。如
border-color
、border-style
的改變。
重繪的影響
重繪相比迴流來說代價較小,因為它只涉及到外觀的重新渲染,而不需要重新計算佈局和尺寸。然而,在一個複雜的頁面中,頻繁的重繪操作也會影響效能。
迴流與重繪的關係
迴流通常會導致重繪,因為在元素的位置或尺寸發生變化後,瀏覽器不僅需要重新計算佈局,還需要重新繪製受影響的元素。然而,重繪不會導致迴流,重繪僅僅是重新繪製元素,而不會涉及佈局變化。
如何最佳化迴流和重繪?
減少迴流和重繪可以顯著提升頁面效能。以下是一些常見的最佳化策略:
避免逐個修改樣式:如果要更改元素的多個樣式屬性,最好使用
class
一次性修改,而不是多次修改不同的樣式屬性。每次修改樣式都會觸發迴流或重繪。
// 不推薦 element.style.width = '100px'; element.style.height = '200px'; // 推薦 element.className = 'new-class'; // 一次性修改多個樣式
批次修改 DOM:儘量減少 DOM 操作的頻率。如果需要對多個元素進行修改,可以使用文件片段(DocumentFragment) 或者 離線 DOM(如
display: none
臨時隱藏)來減少多次操作對頁面效能的影響。避免頻繁的讀取佈局資訊:讀取佈局資訊(如
offsetHeight
、clientWidth
)會觸發迴流,因為瀏覽器必須重新計算佈局來返回正確的值。儘量快取這些值,避免在同一幀中反覆讀取。使用 CSS 動畫替代 JavaScript 動畫:CSS 動畫在瀏覽器中的執行效率通常比 JavaScript 高,因為它們可以由瀏覽器的渲染引擎最佳化,甚至在 GPU 上處理。
使用
will-change
最佳化重繪:對於即將發生變化的屬性(如transform
、opacity
),可以使用will-change
提示瀏覽器進行最佳化:
.animated { will-change: transform, opacity; }
減少複雜的選擇器:複雜的 CSS 選擇器會增加瀏覽器匹配元素的時間,因此儘量使用簡單、高效的選擇器。
總結
迴流 是佈局的重新計算,是較為消耗效能的操作,涉及到頁面佈局變化。
重繪 是頁面外觀的重新繪製,代價小於迴流,但頻繁重繪也會影響效能。
透過減少不必要的 DOM 操作和樣式修改,合理地最佳化程式碼,可以有效提升頁面的渲染效能。