FE Interview Hub
Web Vitals中階

回流 (reflow) 和重繪 (repaint) 是什麼?以及如何優化?

AI 練習作答

什麼是 Reflow(回流)與 Repaint(重繪)?

瀏覽器渲染流程大致為:

JS → Style → Layout(Reflow)→ Paint(Repaint)→ Composite

  • Reflow(回流/重排):元素的幾何屬性(尺寸、位置、結構)改變,瀏覽器必須重新計算 Layout,再重新繪製。
  • Repaint(重繪):元素的外觀屬性(如顏色、背景、visibility)改變,但不影響版面,瀏覽器只需重新 Paint,不需要 Layout。

Reflow 一定伴隨 Repaint;Repaint 不一定會觸發 Reflow。Reflow 的成本遠高於 Repaint。

哪些操作會觸發 Reflow?

  • 新增 / 刪除 DOM 節點
  • 改變元素尺寸:widthheightpaddingmarginborder
  • 改變元素位置:topleftposition(相對定位切換)
  • 改變字體大小 / 行高
  • 視窗 resize、字型載入完成
  • 讀取會強制同步 Layout 的屬性:offsetWidthoffsetHeightclientTopscrollTopgetBoundingClientRect()getComputedStyle()

哪些操作只會觸發 Repaint?

  • colorbackground-colorvisibilityoutlinebox-shadow(部分情況)

如何優化?

  1. 批次修改 DOM / 樣式

    • 多次修改樣式時,改用 class 一次切換,或先 display: none 再操作完再顯示。
    • 使用 DocumentFragmentcloneNode 離線處理 DOM,最後一次插入。
  2. 避免 Layout Thrashing(強制同步佈局)

    • 不要在迴圈中交替「寫入樣式」與「讀取幾何屬性」,先讀後寫。
    // Bad:每次迴圈都觸發 reflow
    for (const el of items) {
      el.style.width = el.offsetWidth + 10 + 'px';
    }
    
    // Good:先讀後寫
    const widths = items.map(el => el.offsetWidth);
    items.forEach((el, i) => el.style.width = widths[i] + 10 + 'px');
    
  3. 使用 transformopacity 做動畫

    • 這兩個屬性不觸發 Layout 與 Paint,只走 Composite(由 GPU 合成),效能最好。
  4. 提升為合成層(Composite Layer)

    • 使用 will-change: transformtransform: translateZ(0) 讓元素獨立合成,避免影響其他元素。
  5. 避免使用 table 佈局

    • <table> 中任何一個元素變動會導致整個 table reflow。
  6. 大量動畫 / 滾動事件搭配 requestAnimationFrame

    • 將視覺更新排進下一幀,避免一幀內重複 reflow。
  7. 虛擬 DOM / 框架 diff

    • React、Vue 透過 diff 批次更新,減少 DOM 操作次數。

小結

類型 觸發時機 成本
Reflow 幾何變化 高(重算 Layout)
Repaint 外觀變化
Composite transform / opacity 低(GPU)

優化核心:減少 Reflow 次數、改用 transform/opacity 做動畫、避免強制同步佈局。

✦ AI 模擬面試

輸入你的答案,AI 即時分析精準度與改進空間

登入後即可使用 AI 評分