頁面渲染性能控制-重繪與迴流

瀏覽器解析代碼過程

頁面的顯示過程分爲如下幾個階段:node

  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,增長border等等,改變頁面佈局了
  4. 窗口resize事件觸發
  5. 最複雜的一種:獲取某些屬性,引起迴流 不少瀏覽器會對迴流作優化,他會等到足夠數量的變化發生,在作一次批處理迴流。
    可是除了render樹的直接變化。
    當獲取一些屬性時,瀏覽器爲了得到正確的值也會觸發迴流。這樣就使得瀏覽器的優化失效了 這些屬性包括app

    offsetTop,     offsetLeft,     offsetWidth,     offsetHeight
       scrollTop/Left/Width/Height,
       clientTop/Left/Width/Height,
       width,height
       調用了getComputedStyle(), 或者 IE的 currentStyle

這段兒代碼是抄的,哈哈,大概解釋一下樣式改變引發的重繪和迴流佈局

var s = document.body.style;

s.padding = "2px"; // 迴流+重繪

s.border = "1px solid red"; // 再一次 迴流+重繪

s.color = "blue"; // 再一次重繪

s.backgroundColor = "#ccc"; // 再一次 重繪

s.fontSize = "14px"; // 再一次 迴流+重繪, 沒想到吧,改變字體大小也會迴流

document.body.appendChild(document.createTextNode('abc!'));  // 添加node,再一次 迴流+重繪

能夠看出,迴流必定伴隨着重繪,而重繪卻能夠單獨出現性能

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

減小回流

  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
相關文章
相關標籤/搜索