本文是面試匯總分支——重繪和重排的區別。
重繪不一定需要重排(比如顏色的改變),重排必然導致重繪(比如改變網頁位置)
DOM的變化影響了元素的幾何屬性,瀏覽器需要重新計算元素的幾何屬性,同時其他元素的幾何屬性和位置也會受到影響,瀏覽器會使渲染樹中受到影響的部分失效,並重新構造渲染樹,這個過程是重排,瀏覽器會重新繪制受到影響的部分到屏幕,這個過程叫重繪。
1>重排(Reflow):當渲染樹的一部分必須更新並且節點的尺寸發生了變化,瀏覽器會使渲染樹中受到影響的部分失效,並重新構造渲染樹。
2>重繪(Repaint):是在一個元素的外觀被改變所觸發的瀏覽器行為,瀏覽器會根據元素的新屬性重新繪制,使元素呈現新的外觀。比如改變某個元素的背景色、文字顏色、邊框顏色等等
3>引發重排
1.添加、刪除可見的dom
2.元素的位置改變
3.元素的尺寸改變(外邊距、內邊距、邊框厚度、寬高、等幾何屬性)
4.頁面渲染初始化
5.瀏覽器窗口尺寸改變
6.獲取某些屬性。當獲取一些屬性時,瀏覽器為取得正確的值也會觸發重排,它會導致隊列刷新,這些屬性包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。所以,在多次使用這些值時應進行緩存。
4>優化:
瀏覽器自己的優化:
瀏覽器會維護1個隊列,把所有會引起重排,重繪的操作放入這個隊列,等隊列中的操作到一定數量或者到了一定時間間隔,瀏覽器就會flush隊列,進行一批處理,這樣多次重排,重繪變成一次重排重繪
減少 reflow/repaint:
(1)不要一條一條地修改 DOM 的樣式。可以先定義好 css 的 class,然后修改 DOM 的 className。
(2)不要把 DOM 結點的屬性值放在一個循環里當成循環里的變量。
(3)為動畫的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他們的 CSS 是不會 reflow 的。
(4)千萬不要使用 table 布局。因為可能很小的一個小改動會造成整個 table 的重新布局。(table及其內部元素除外,它可能需要多次計算才能確定好其在渲染樹中節點的屬性,通常要花3倍於同等元素的時間。這也是為什么我們要避免使用table做布局的一個原因。)
(5)不要在布局信息改變的時候做查詢(會導致渲染隊列強制刷新)
感謝:重繪和重排