回顧
URL->字符流->詞流(token)->DOM樹->包含樣式信息的DOM樹-計算了每一個元素的位置和大小(排版)javascript
渲染
- 定義:把元素變成位圖的過程(每個元素對應的盒變成位圖,一個元素可能對應多個盒(好比 inline 元素,可能分紅多行)
- 位圖:在內存裏創建一張二維表格,把一張圖片的每一個像素對應的顏色保存進去(位圖信息也是 DOM 樹中佔據瀏覽器內存最多的信息,咱們在作內存佔用優化時,主要就是考慮這一部分)
-
分類:圖形和文字java
- 最廣泛的狀況下,渲染過程生成的位圖尺寸跟它在上一步排版時佔據的尺寸相同,不少屬性會影響渲染位圖的大小,好比陰影,爲了優化,瀏覽器實際的實現中會把陰影做爲一個獨立的盒來處理
- 通常的操做系統會提供一個底層庫來支持渲染:Android(Skia)Windows(GDI)瀏覽器會作一個兼容層來處理掉平臺差別
- 渲染過程:不會把子元素繪製到渲染的位圖上的,當父子元素的相對位置發生變化時,能夠保證渲染的結果可以最大程度被緩存,減小從新渲染
- 輸入框實現:渲染過程除了位圖,最終繪製上去還產生一個"熱區",這個「熱區」不但跟你說的input相關,還跟用戶選擇、鼠標事件和scroll等交互相關(太複雜啦,winter沒有講)
合成
- 定義:爲一些元素建立一個「合成後的位圖」(咱們把它稱爲合成層),把一部分子元素渲染到合成的位圖上面,性能優化行爲,非瀏覽器必須
-
合成的策略:最大限度減小繪製次數,「猜想」可能變化的元素,把它排除到合成以外瀏覽器
- 主流瀏覽器通常根據 position、transform 等屬性來決定合成策略,來「猜想」這些元素將來可能發生變化
- 新的 CSS 標準中,規定了 will-change 屬性,能夠由業務代碼來提示瀏覽器的合成策略
- 🌰
合成策略可以把 a、b 兩個 div 合成,而不把 c 合成
在實際場景中,咱們的 b 可能有不少複雜的子元素,因此當合成命中時,性能提高收益很是之高
<div id="a">
<div id="b">...</div>
<div id="c" style="transform:translate(0,0)"></div>
</div>
document.getElementById("c").style.transform = "translate(100px, 0)";
繪製
做業:
用 JavaScript 實現一個玩具瀏覽器(用canvas模擬一個iframe嗎)性能優化