【14】winter重學前端 筆記 - 瀏覽器:一個瀏覽器是如何工做的?(階段五)渲染

回顧

URL->字符流->詞流(token)->DOM樹->包含樣式信息的DOM樹-計算了每一個元素的位置和大小(排版)javascript

渲染

  • 定義:把元素變成位圖的過程(每個元素對應的盒變成位圖,一個元素可能對應多個盒(好比 inline 元素,可能分紅多行)
  • 位圖:在內存裏創建一張二維表格,把一張圖片的每一個像素對應的顏色保存進去(位圖信息也是 DOM 樹中佔據瀏覽器內存最多的信息,咱們在作內存佔用優化時,主要就是考慮這一部分)
  • 分類:圖形和文字java

    • 圖形類:盒的背景、邊框、SVG 元素、陰影等特性算法

      • 盒的特性如何繪製,每個都有對應的標準規定,不詳細探究
    • 文字類canvas

      • 分類:分爲像素字形和矢量字形(會在 6px 8px 等小尺寸提供像素字形,比較大的尺寸則提供矢量字形)
  • 最廣泛的狀況下,渲染過程生成的位圖尺寸跟它在上一步排版時佔據的尺寸相同,不少屬性會影響渲染位圖的大小,好比陰影,爲了優化,瀏覽器實際的實現中會把陰影做爲一個獨立的盒來處理
  • 通常的操做系統會提供一個底層庫來支持渲染: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)";

繪製

  • 定義:把「位圖最終繪製到屏幕上,變成肉眼可見的圖像」的過程,實際上就是按照 z-index 把它們依次繪製到屏幕
  • 瀏覽器不處理,把要顯示的位圖交給操做系統
  • 限制繪製的面積(換一個角度理解重繪repaint):緩存

    • 問題:鼠標劃過瀏覽器顯示區域。這個過程當中,鼠標的每次移動,都形成了從新繪製,若是咱們不從新繪製,就會產生大量的鼠標殘影
    • 解決:「髒矩形」算法--把屏幕均勻地分紅若干矩形區域,從新繪製髒矩形區域時,把全部與矩形區域有交集的合成層(位圖)的交集部分繪製便可。

做業:

用 JavaScript 實現一個玩具瀏覽器(用canvas模擬一個iframe嗎)性能優化

相關文章
相關標籤/搜索