细谈页面回流与重绘
你將了解到:
什么是回流 什么是重繪 回流何時發生 重繪何時發生 如何避免回流和重繪 復制代碼帶著上面的問題,我們一探究竟
什么是回流
回流:英文是reflow
當render tree中的一部分(或全部),因為元素的規模尺寸、布局、隱藏等改變 而需要重新構建,這就是回流(reflow) 復制代碼- 每個頁面至少回流一次,即頁面首次加載
- 回流時,瀏覽器會使渲染樹中受到影響的部分失效,并重新構造這部分渲染樹
- 回流完成后,瀏覽器會重新繪制受影響的部分,是重繪過程
什么是重繪
重繪:英文是repaints
當render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外 觀、風格,而不影響布局(例如:background-color),則稱為重繪(repaints) 復制代碼特點:回流必將引起重繪,重繪不一定引起回流 回流比重繪的代價更高
回流何時發生
當頁面布局和幾何屬性改變時就需要回流
下述情況會發生瀏覽器回流:
(1)添加或者刪除可見的DOM元素; (2)元素位置改變; (3)元素尺寸改變——邊距、填充、邊框、寬度和高度 (4)內容改變——比如文本改變或者圖片大小改變而引起的計算值寬度和高度改變; (5)頁面渲染初始化; (6)瀏覽器窗口尺寸改變——resize事件發生時; 復制代碼let box = document.getElementById("box").style; box.padding = "2px"; // 回流+重繪 box.border = "1px solid red"; // 再一次 回流+重繪 box.fontSize = "14px"; // 回流+重繪 document.getElementById("box").appendChild(document.createTextNode('abc!')); 復制代碼重繪何時發生
元素的屬性或者樣式發生變化。
let box = document.getElementById("box").style; box.color = "red"; // 重繪 box.backgroud-color = "blue"; // 重繪 document.getElementById("box").appendChild(document.createTextNode('abc!')); 復制代碼因回流的開銷較大,如果每個操作都去回流重繪的話,瀏覽器可能就會受不了。所以很多瀏覽器都會優化這些操作。
多次的回流、重繪變成一次回流重繪:
瀏覽器會維護1個隊列,把所有會引起回流、重繪的操作放入這個隊列,等 隊列中的操作到了一定的數量或者到了一定的時間間隔,瀏覽器就會flush 隊列,進行一個批處理。 復制代碼但是有時上面的方法會失效,原因是:
有些情況,當請求向瀏覽器請求一些style信息的時候,就會讓瀏覽器強制flush隊列,比如:(1)offsetTop, offsetLeft, offsetWidth, offsetHeight (2) scrollTop/Left/Width/Height (3)clientTop/Left/Width/Height (4)width,height (5)請求了getComputedStyle(), 或者 IE的 currentStyle 復制代碼當你請求上面的一些屬性的時候,瀏覽器為了給你最精確的值,需要flush隊列,因為隊列中可能會有影響到這些值的操作。即使你獲取元素的布局和樣式信息跟最近發生或改變的布局信息無關,瀏覽器都會強行刷新渲染隊列。
這樣以來,瀏覽器的優化就顯得力不從心,所以我們需要一些方法,盡可能的避免或減少瀏覽器的回流、重繪
如何避免、減少回流和重繪
- 減少對render tree的操作【合并多次多DOM和樣式的修改】
- 減少對一些style信息的請求,盡量利用好瀏覽器的優化策略
參考資料:
- 前端進階(二)重繪和回流
- 重繪與回流
- 頁面的重繪與回流,以及如何優化
轉載于:https://juejin.im/post/5c87bd375188257e3e47fdc5
總結
- 上一篇: 性能测试总结(一)---基础理论篇(转载
- 下一篇: C#浅拷贝与深拷贝区别