回流 reflow 重繪 repaint

2021-09-11 08:41:52 字數 1637 閱讀 2883

首先我們要明白的是,頁面的顯示過程分為以下幾個階段:

生成dom樹(包括display:none的節點)

在dom樹的基礎上根據節點的集合屬性(margin,padding,width,height等)生成render樹(不包括display:none,head節點,但是包括visibility:hidden的節點)

在render樹的基礎上繼續渲染顏色背景色等樣式

reflow:

當render樹的一部分或者全部因為大小邊距等問題發生改變而需要重建的過程,叫做回流

repaint:

當諸如顏色背景等不會引起頁面布局變化,而只需要重新渲染的過程叫做重繪

通過上述定義,可以很明顯看出,重繪的代價要比回流小,畢竟重繪只涉及樣式的改變,不涉及到布局。

頁面渲染初始化

dom結構變化,比如刪除了某個節點

render樹變化,比如減少了padding

視窗resize事件觸發

最複雜的一種:獲取某些屬性,引發回流 很多瀏覽器會對回流做優化,他會等到足夠數量的變化發生,在做一次批處理回流。 但是除了render樹的直接變化。 當獲取一些屬性時,瀏覽器為了獲得正確的值也會觸發回流。這樣就使得瀏覽器的優化失效了

這些屬性包括:

var s = document.body.style;

s.padding =

"2px"

; // 回流+重繪

s.border =

"1px solid red"

; // 再一次 回流+重繪

s.color =

"blue"

; // 再一次重繪

s.backgroundcolor =

"#ccc"

; // 再一次 重繪

s.fontsize =

"14px"

; // 再一次 回流+重繪

// 新增node,再一次 回流+重繪

'abc!'

));

可以看出,回流一定伴隨著重繪,而重繪卻可以單獨出現

回流對效能產生了一定的影響,儘管瀏覽器機智地幫我們進行了批處理,但是仍然存在著上述諸多闊怕的屬性,一獲取就回流。怎麼解決?

避免逐項更改樣式。最好一次性更改style屬性,或者將樣式列表定義為class並一次性更改class屬性。

避免迴圈操作dom。建立乙個documentfragment或div,在它上面應用所有dom操作,最後再把它新增到window.document。

避免多次讀取offsetleft等屬性。無法避免則將它們快取到變數。

將複雜的元素絕對定位或固定定位,使它脫離文件流。否則回流代價十分高

補充:改變字型大小會引發回流

display:none和visibility:hidden會產生回流與重繪嗎?

display:none指的是元素完全不陳列出來,不佔據空間,涉及到了dom結構,故產生reflow與repaint

visibility:hidden指的是元素不可見但存在,保留空間,不影響結構,故只產生repaint

**tuna

Reflow 回流 和Repaint 重繪

首先我們要明白的是,頁面的顯示過程分為以下幾個階段 1 生成dom樹 包括display none的節點 2 在dom樹的基礎上根據節點的集合屬性 margin,padding,width,height等 生成render樹 不包括display none,head節點,但是包括visibility...

回流 reflow 和重繪 repaint

首先先介紹瀏覽器解析的工作原理 1.解析html文件建立dom樹 2.解析css 包含外部css以及js生成的 構建渲染樹,計算出節點的樣式 3.布局渲染樹,以根節點遞迴呼叫,計算每乙個節點的大小,位置等,給出每乙個節點出現在螢幕的精準目標 4.繪製渲染樹,遍歷渲染樹,每個幾點使用ui後端層來繪製 ...

reflow 回流 和repaint 重繪

dom節點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等,這個過程稱為reflow 當盒模型的位置,大小以及其他屬性,如顏色,字型,等確定下來之後,瀏覽器便開始繪製內容,這個過程稱為repaint。頁面在首次載入時必然會經歷reflow和repaint。reflow和rep...