瀏覽器渲染機制
- 瀏覽器獲取到HTML,解析生成DOM樹,獲取到CSS,生成CSSOM樹
- 將DOM樹和CSSOM樹結合,生成Render Tree(渲染樹)
- Layout(回流)
- Painting(重繪)
- Display:將渲染之后的元素展示在頁面
Layout(回流/重排)
當 Render Tree 中的一部分(或者全部)因為元素的規(guī)模尺寸,布局,隱藏等改變而需要重新構建。這就稱為回流
Painting(重繪)
當 Render Tree 中的一些元素需要更新屬性時,而這些屬性只影響元素的外觀,風格,而不會影響布局時,就叫做重繪。
如何觸發(fā)回流
注:回流一定會重繪,但是重繪不一定回流
- 頁面第一次加載
- 元素尺寸改變(字體顏色,元素背景等只觸發(fā)重繪)
- 元素位置改變
- 元素內容改變(文本換成圖片,input輸入時)
- 添加/刪除可見DOM元素(元素display:none不會發(fā)生重排;visibility:hidden顯示/隱藏不影響重排)
- 瀏覽器窗口尺寸改變
- 計算 offsetWidth/offsetHeight 等操作時
如何優(yōu)化
CSS優(yōu)化:
- 使用 transform 代替 定位使用 (top)
- 使用 visibility 替換 display:none,前者只會引起重繪,后者會發(fā)生回流(布局改變)
- 避免使用 table 布局方式(可能很小的一個改動會造成整個table的重新布局)
- 盡可能在DOM樹的最末端改變class(回流是不可避免的,但可以減少其影響。盡可能在DOM樹的最末端改變class,可以限制了回流的范圍,使其影響盡可能少的節(jié)點)
- 避免設置多層內聯樣式,CSS 選擇符從右往左匹配查找,避免節(jié)點層級過多(例:div>span>em)
- 將動畫效果應用到position屬性為absolute或fixed的元素上(避免影響其他元素的布局,這樣只是一個重繪,而不是回流,同時,控制動畫速度可以選擇 requestAnimationFrame)
- 避免使用CSS表達式,可能會引發(fā)回流
- 將頻繁重繪或者回流的節(jié)點設置為圖層,圖層能夠阻止該節(jié)點的渲染行為影響別的節(jié)點,例如will-change、video、iframe、canvas等標簽,瀏覽器會自動將該節(jié)點變?yōu)閳D層
- 啟用CSS3 硬件加速(GPU加速),使用css3硬件加速,可以讓transform、opacity、filters這些動畫不會引起回流重繪 。但是對于動畫的其它屬性,比如background-color這些,還是會引起回流重繪的,不過它還是可以提升這些動畫的性能
JS優(yōu)化:
- 避免頻繁操作樣式,(最好一次性重寫style屬性,或者將樣式列表定義為class并一次性更改class屬性)
- 避免頻繁操作DOM(創(chuàng)建一個documentFragment,在它上面應用所有DOM操作,最后再把它添加到文檔中)
- 避免頻繁讀取會引發(fā)回流/重繪的屬性,如果確實需要多次使用,就用一個變量緩存起來
參考文檔: