瀏覽器的渲染機制
主要分爲以下幾個步驟:
- 解析HTML(HTML Parser)
- 構建DOM樹(DOM Tree)
- 渲染樹構建(Render Tree)
- 繪製渲染樹(Painting)
瀏覽器取回代碼後,首先會構造DOM樹,根據HTML標籤,構造DOM樹。
之後會解析CSS樣式,解析的順序是瀏覽器的樣式
-> 用戶自定義的樣式
-> 頁面的link標籤等引進來的樣式
-> 寫在style標籤裏面的內聯樣式
網頁生成的時候,至少會渲染一次。用戶訪問的過程中,還會不斷重新渲染。
重新渲染,就需要重新生成佈局和重新繪製。前者叫做重排(reflow),後者叫做重繪(repaint)。
需要注意的是,重繪不一定需要重排,重排必然導致重繪。
爲了提高網頁性能,就要降低"重排"和"重繪"的頻率和成本,儘量少觸發重新渲染。
慎重選擇高消耗的樣式
什麼 CSS 屬性是高消耗的?就是那些繪製前需要瀏覽器進行大量計算的屬性。
-
box-shadows
-
border-radius
-
transparency
-
transforms
-
CSS filters(性能殺手)
什麼是reflow
瀏覽器爲了重新渲染部分或整個頁面,重新計算頁面元素位置和幾何結構的進程叫做reflow
.
通俗點說就是當開發人員定義好了樣式後(也包括瀏覽器的默認樣式),瀏覽器根據這些來計算並根據結果將元素放到它應該出現的位置上,這個過程叫做reflow
.
由於reflow
是一種瀏覽器中的用戶攔截操作,所以我們瞭解如何減少reflow次數,及DOM的層級,css效率對refolw次數的影響是十分有必要的。
reflow(迴流)是導致DOM腳本執行效率低的關鍵因素之一,頁面上任何一個節點觸發了reflow,會導致它的子節點及祖先節點重新渲染。
<body> <div class="hello"> <h4>hello</h4> <p><strong>Name:</strong>BDing</p> <h5>male</h5> <ol> <li>coding</li> <li>loving</li> </ol> </div> </body>
當p節點上發生reflow時,hello和body也會重新渲染,甚至h5和ol都會收到影響。
什麼時候會導致reflow發生呢?
- 改變窗口大小
- 改變文字大小
- 添加/刪除樣式表
- 內容的改變,(用戶在輸入框中寫入內容也會)
- 激活僞類,如:hover
- 操作class屬性
- 腳本操作DOM
- 計算offsetWidth和offsetHeight
- 設置style屬性
常見的重排元素 | ||||
---|---|---|---|---|
width | height | padding | margin | |
display | border-width | border | top | |
position | font-size | float | text-align | |
overflow-y | font-weight | overflow | left | |
font-family | line-height | vertical-align | right | |
clear | white-space | bottom | min-height |
怎麼減少 Reflow
-
不要一條一條地修改 DOM 的樣式,預先定義好 class,然後修改 DOM 的
className
-
把 DOM 離線後修改,比如:先把 DOM 給
display:none
(有一次 Reflow),然後你修改100次,然後再把它顯示出來 -
不要把 DOM 結點的屬性值放在一個循環裏當成循環裏的變量
-
儘可能不要修改影響範圍比較大的 DOM
-
爲動畫的元素使用絕對定位
absolute / fixed
-
不要使用
table
佈局,可能很小的一個小改動會造成整個 table 的重新佈局
什麼是repaint
repaint是在一個元素的外觀被改變,但沒有改變佈局的情況下發生的,如改變了visibility、outline、background等。當repaint發生時,瀏覽器會驗證DOM樹上所有其他節點的visibility屬性。·
通俗來說,就是當各種盒子的位置、大小以及其他屬性,例如顏色、字體都確定下來後,瀏覽器便把這些元素都按照各自的特性繪製一遍,於是頁面的內容出現了,這個過程叫做repaint
避免過分重繪(Repaints)
當元素改變的時候,將不會影響元素在頁面當中的位置(比如 background-color
, border-color
, visibility
),瀏覽器僅僅會應用新的樣式重繪此元素,此過程稱爲 Repaint
。
常見的重繪元素 | ||||
---|---|---|---|---|
color | border-style | visibility | background | |
text-decoration | background-image | background-position | background-repeat | |
outline-color | outline | outline-style | border-radius | |
outline-width | box-shadow | background-size |
優化動畫
css3 動畫是優化的重中之重。除了做到上面兩點,減少 Reflow 和 Repaints
之外,還需要注意以下方面。
啓用 GPU 硬件加速
GPU
(Graphics Processing Unit) 是圖像處理器
。GPU
硬件加速是指應用 GPU
的圖形性能對瀏覽器中的一些圖形操作交給 GPU
來完成,因爲 GPU
是專門爲處理圖形而設計
,所以它在速度和能耗
上更有效率。
GPU
加速可以不僅應用於3D,而且也可以應用於2D。這裏, GPU
加速通常包括以下幾個部分:Canvas2D
,佈局合成(Layout Compositing)
, CSS3轉換(transitions)
,CSS3 3D變換(transforms)
,WebGL
和視頻(video)
。
/* * 根據上面的結論 * 將 2d transform 換成 3d * 就可以強制開啓 GPU 加速 * 提高動畫性能 */ div { transform: translate(10px, 10px); } div { transform: translate3d(10px, 10px, 0); }
需要注意的是,開啓硬件加速相應的也會有額外的開銷,參見這篇文章 CSS 硬件加速的好與壞·
參考以下文章: