回流(reflow)與重繪(repaint)


回流(reflow)與重繪(repaint)

很早之前就聽說過回流與重繪這兩個名詞,但是並不理解它們的含義,也沒有深究過,今天看了一套網易的題目,涉及到了這兩個概念,於是想要把它們倆弄清楚。。。

一、概念

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

1、生成DOM樹(包括display:none的節點)

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

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

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

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

通過上述定義,可以很明顯看出,重繪的代價要比回流小,畢竟重繪只涉及樣式的改變,不涉及到布局。重繪就好像給人染了一個頭發,而回流相當於給人做了一次抽脂手術

二、什么會引起回流

這也是網易題目的出法

  1. 頁面渲染初始化
  2. DOM結構變化,比如刪除了某個節點;骨頭都被打斷了,肯定比抽脂更嚴重,所以會引發回流
  3. render樹變化,比如減少了padding;也就是進行抽脂手術
  4. 窗口resize事件觸發
  5. 最復雜的一種:獲取某些屬性,引發回流 很多瀏覽器會對回流做優化,他會等到足夠數量的變化發生,在做一次批處理回流。 但是除了render樹的直接變化。 當獲取一些屬性時,瀏覽器為了獲得正確的值也會觸發回流。這樣就使得瀏覽器的優化失效了
      這些屬性包括
    1. offsetTop, offsetLeft, offsetWidth, offsetHeight
    2. scrollTop/Left/Width/Height
    3. clientTop/Left/Width/Height
    4. width,height
    5. 調用了getComputedStyle(), 或者 IE的 currentStyle
我在別處抄來了一段代碼,嘻嘻
?
1
2
3
4
5
6
7
8
var s = document.body.style;
s.padding = "2px" ; // 回流+重繪
s.border = "1px solid red" ; // 再一次 回流+重繪
s.color = "blue" ; // 再一次重繪
s.backgroundColor = "#ccc" ; // 再一次 重繪
s.fontSize = "14px" ; // 再一次 回流+重繪
// 添加node,再一次 回流+重繪
document.body.appendChild(document.createTextNode( 'abc!' ));

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

可以理解為,路人甲摔斷了腿或者抽脂之后,病怏怏導致頭發也變白了(回流+重繪);但是炮灰乙卻僅僅是去村口王師傅那里燙了頭(重繪)

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

三、減少回流

  1. 避免逐項更改樣式。最好一次性更改style屬性,或者將樣式列表定義為class並一次性更改class屬性。
  2. 避免循環操作DOM。創建一個documentFragment或div,在它上面應用所有DOM操作,最后再把它添加到window.document。
  3. 避免多次讀取offsetLeft等屬性。無法避免則將它們緩存到變量。
  4. 將復雜的元素絕對定位或固定定位,使它脫離文檔流。否則回流代價十分高

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

回到網易的問題,並適當做延伸:display:none和visibility:hidden會產生回流與重繪嗎?

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM