reflow(迴流)與repaint(重繪)的區別及優化

1.迴流及重繪的概念javascript

迴流(reflow):當render tree中的元素的寬高、佈局、顯示、隱藏或元素內部文字結結構發生改變時,會影響自身及其父元素、甚至追溯到更多的祖先元素髮生改變,則會致使元素內部、周圍甚至整個頁面的從新渲染,頁面發生重構,迴流就產生了。css

重繪(repaint):元素的結構(寬高、佈局、顯示隱藏、內部文字大小)未發生改變,只是元素的外觀樣式發生改變,好比背景顏色、內部文字顏色、邊框顏色等。此時會引發瀏覽器重繪,顯然重繪的速度快於迴流。html

迴流必定會觸發重繪,重繪不必定觸發迴流。java

2.迴流重繪對性能的影響瀏覽器

這裏瞭解一個知識點:渲染css樣式會影響js執行的時間,使得加載js腳本變慢。緣由以下:dom

瀏覽器渲染一個網頁的時候會啓用兩條線程:一條渲染javascript 腳本,另外一條渲染 ui 即css 樣式的渲染。但這兩條線程是互斥的,當javascript 線程運行的時候 ui 線程則會停止暫停,反之亦然。由於當ui 線程運行對頁面進行渲染的時候, js 腳本不免會涉及到頁面視圖上的一些樣式的改變,爲了使這個改變動加準確 js 腳本只好等待ui 線程渲染完成的時候纔去執行。ide

因此當一個頁面的元素樣式改動頻繁的時候ui 線程就會持續渲染,形成js 代碼反應慢半拍,卡頓的狀況。迴流和重繪都會使得ui線程渲染時間加長,太多就會使得網站性能變差,所以要儘可能減小reflow和repaint。佈局

3.如何減小回流和重繪性能

 致使迴流發生的狀況以下:動畫

  • 改變窗口大小
  • 改變文字大小
  • 內容的改變,如用戶在輸入框中敲字
  • 激活僞類,如:hover
  • 操做class屬性
  • 腳本操做DOM
  • 計算offsetWidth和offsetHeight
  • 設置style屬性

 對應的css屬性以下:

  • 盒子模型相關屬性
  • 定位及浮動屬性
  • 節點內部的文字結構

  

 致使重繪的css屬性以下:

  

 

  減小回流和重繪注意點以下:

1:用transform 代替 top,left ,margin-top, margin-left... 這些位移屬性

2:用opacity 代替 visibility,可是要同時有translate3d 或 translateZ 這些能夠建立的圖層的屬性存在才能夠阻止迴流

可是第二點通過個人實驗,發現若是不加 transform: translateZ(0) 配合opacity的話仍是會產生迴流的,而只用visibility 就只會產生重繪不會迴流

而  opacity 加上 transform: translateZ/3d  這個屬性以後便不會發生迴流和重繪了

3:不要使用 js 代碼對dom 元素設置多條樣式,選擇用一個 className 代替之。

4:若是確實須要用 js 對 dom 設置多條樣式那麼能夠將這個dom 先隱藏,而後再對其設置

5:不要在循環內獲取dom 的樣式例如:offsetWidth, offsetHeight, clientWidth, clientHeight... 這些。瀏覽器有一個迴流的緩衝機制,即多個迴流會保存在一個棧裏面,當這個棧滿了瀏覽器便會一次性觸發全部樣式的更改且刷新這個棧。可是若是你屢次獲取這些元素的實際樣式,瀏覽器爲了給你一個準確的答案便會不停刷新這個緩衝棧,致使頁面迴流增長。

因此爲了不這個問題,應該用一個變量保存在循環體外。

6:不要使用table 佈局,由於table 的每個行甚至每個單元格的樣式更新都會致使整個table 從新佈局

7:動畫的速度按照業務按需決定。

8:對於頻繁變化的元素應該爲其加一個 transform 屬性,對於視頻使用video 標籤

9:必要時能夠開啓 GPU 加速,可是不能濫用

相關參考:

http://www.javashuo.com/article/p-xtoszrsh-gg.html

http://www.javashuo.com/article/p-tfclhmbv-dt.html

相關文章
相關標籤/搜索