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.如何減小回流和重繪性能
致使迴流發生的狀況以下:動畫
對應的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 加速,可是不能濫用 |
相關參考: