什麼是重繪repaint?什麼是迴流reflow?

GeekQiaQia發表於2019-04-17

什麼是重繪?

  • 重繪(repaint): 當我們對Dom的修改,導致了樣式的變化比如:顏色、font-weight等屬性的時候,卻並未影響到幾何屬性(:比如盒子的weidth/height/position/display等)時,瀏覽器不需要重新計算元素的幾何屬性,直接為該元素繪製新的樣式;

  • 迴流(reflow): 當我們對DOM的修改引發了DOM幾何尺寸的變化時候(比如:修改了元素的width/height/display:),瀏覽器需要重新計算元素的幾何屬性;這時候,會影響到其他元素的幾何屬性和位置,然後再講計算結果繪製出來;這個過程叫做迴流(重排)

迴流必定會發生重繪,重繪不一定會引發迴流 當我們在頁面初始化的時候,或者互動過程中,存在著頻繁的重繪或者回流,這個過程,會很大程度的影響效能;因為迴流所需要的成本比重繪高的多,所以,能夠使用重繪的方式解決的問題,儘量避免使用迴流的方式解決;

常見引起迴流的屬性和方法:

  • 任何能夠改變幾何資訊的操作(元素的位置或者大小),都會觸發迴流;
    • 新增或者刪除可見的DOM元素;
    • 元素尺寸的改變:margin /padding/border/width/height;
    • 內容變化:input/textarea輸入內容時;
    • 瀏覽器視窗尺寸改變----resize事件發生時;
    • 計算offsetWith/height屬性時;
    • 設定style屬性的值;

常見引起重繪屬性和方法:

  • color
  • visibility
  • text-decoration
  • background /-image/position/repeat/size
  • outline/-color/style/width
  • border-style/radius
  • box-shadow

如何減少迴流、重繪:

  • 使用 transform 替代 top

  • 使用 visibility 替換 display: none ,因為前者只會引起重繪,後者會引發迴流(改變了佈局)

  • 不要把節點的屬性值放在一個迴圈裡當成迴圈裡的變數。

    • 獲取offsetTop 導致迴流; for(let i=0;i<1000;i++){ console.log(document.querySelector('.container').style.offsetTop); }
  • 不要使用 table 佈局,可能很小的一個小改動會造成整個 table 的重新佈局

  • 動畫實現的速度的選擇,動畫速度越快,迴流次數越多,也可以選擇使用 requestAnimationFrame

  • CSS 選擇符從右往左匹配查詢,避免節點層級過多

  • 將頻繁重繪或者回流的節點設定為圖層,圖層能夠阻止該節點的渲染行為影響別的節點。比如對於 video 標籤來說,瀏覽器會自動將該節點變為圖層

參考

相關文章