1. 程式人生 > >前端效能優化第二篇-迴流和重繪

前端效能優化第二篇-迴流和重繪

前端效能優化第二篇-迴流和重繪

先給自己持續更新的專欄打個廣告,歡迎大家讀一讀專欄中的其他文章,戳一戳->前端效能優化

瀏覽器渲染過程

先請今天的主角“迴流”和“重繪”在後臺等一下,我們先來看看瀏覽器渲染頁面的過程,不要跳過這個重要的部分啊~

當瀏覽器得到頁面的時候,就開始了它的渲染過程:
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