前端效能優化第二篇-迴流和重繪
阿新 • • 發佈:2018-12-25
前端效能優化第二篇-迴流和重繪
先給自己持續更新的專欄打個廣告,歡迎大家讀一讀專欄中的其他文章,戳一戳->前端效能優化
瀏覽器渲染過程
先請今天的主角“迴流”和“重繪”在後臺等一下,我們先來看看瀏覽器渲染頁面的過程,不要跳過這個重要的部分啊~
當瀏覽器得到頁面的時候,就開始了它的渲染過程:
1. 解析HTML,構建DOM樹(包括了發起http請求來獲取連結的內容)
2. 解析CSS
3. 合併DOM樹和CSS規則樹,生成reader樹
4. 佈局render樹(Layout/reflow),計算元素的位置,大小
5. 繪製render樹,繪製頁面畫素資訊
上面就是大致的流程了,進行一點簡單的解釋
構建DOM樹
- 單個節點的構建經過了
Bytes -> characters -> tokens -> nodes -> object model
的過程 - 整個樹的構建利用了棧結構,當一個元素的所有子節點構建完成後才去構建下一個兄弟節點(類似深度優先遍歷樹)
構建CSSOM樹
當計算每個節點樣式的時候,瀏覽器會根據優先順序從低到高的順序設定這個節點的屬性,從全域性屬性開始,一直尋找到這個節點的具體屬性。這個CSSOM會部分替換瀏覽器自己的預設樣式表。
生成render樹
這個渲染的過程是從DOM的根節點開始進行render過程,在這個過程中會跳過不佔據空間的節點,比如設定了display:none
visibility:hidden; opacity:0;
的元素。
reflow的觸發
- 頁面第一次渲染
- DOM樹發生變化(新增DOM節點、新增內容)
- 元素位置或大小變化
- 瀏覽器視窗大小變化
- 獲取屬性(這個影響不在於改變了頁面,而是破壞了瀏覽器的進行的批處理迴流優化)
一些屬性和方法
- clientWidth、clientHeight、clientTop、clientLeft
- offsetWidth、offsetHeight、offsetTop、offsetLeft
- scrollWidth、scrollHeight、scrollTop、scrollLeft
- scrollIntoView()、scrollIntoViewIfNeeded()
- getComputedStyle()
- getBoundingClientRect()
- scrollTo()
repaint的觸發
- 迴流必定會引起重繪
- 顏色,透明度,字型等屬性的改變會引起重繪
一個明顯的結論:迴流比重繪代價更高
優化方法
瀏覽器本身是有一定的優化策略的,比如維護一個引起迴流 / 重繪的佇列,將所有引起迴流重繪的操作放入佇列,進行批處理。這樣就能讓多次操作變成一次操作,從而提升效率。同時,如果某些頁面內容的改變很重要,想要第一時間完成,也可以寫程式碼強行提前佇列操作。
日常注意點:
- 將多次頁面樣式改變合併成一次操作
- 將需要多次重排的元素,設定為absolute或者fixed,元素脫離了文件流,不會影響別的元素
- 對一個有多個層次的dom節點,構建完成之後再插入頁面中,而不要一步一步新增
- 可以先把元素display:none,改變內容完成之後再diaplay:block