Life of a Pixel 學習筆記

前言

Life of a Pixel 演講的學習筆記。瀏覽器的渲染過程極爲的複雜,演講的語速也特別的快,因此若有錯誤請及時指出。css

Content

前端的全部代碼統稱爲Content,好比html,js,css,圖片,視頻等。html

在Chromium代碼架構上Content命名空間包含了,黃色框內的全部內容。在Chromium代碼中由WebContent類表示,WebContent類中封裝了渲染進程。前端

image.png

Chromium

Chromium是Google的開源項目,Chrome瀏覽器就是基於Chromium代碼實現,Edge,Opera也是基於Chromium代碼。git

Blink 瀏覽器排版引擎

Blink是瀏覽器排版引擎,屬於Chromium中的一部分。Blink屬於Content中渲染過程代碼的子集。github

總結一下:在Chromium中WebContent類負責Content的渲染,渲染過程交由Blink實現web

初次渲染階段

parsing(解析HTML)-> style (生成樣式規則模型) -> layout(生成佈局對象)-> compositing update (輸入合成)-> paint(繪製)-> commit(提交)-> tiling(切割)-> raster(柵格化)-> draw quads -> display(顯示到屏幕上)瀏覽器

open gl

瀏覽器並不能只靠本身將網頁渲染到屏幕上,瀏覽器的渲染須要使用底層操做系統提供的圖形庫,好比OpenGL API。可是OpenGL並不認識Html,Css這些內容,因此須要經過瀏覽器的Web Content須要將Html,Css轉換成OpenGL能夠識別的內容,而後經過OpenGL渲染到屏幕上。緩存

在渲染到屏幕以後,須要監聽並響應,JavaScript,用戶輸入,異步加載,動畫,滾動,縮放,而後進行渲染更新。對於一些更新渲染,是不須要從頭走徹底部的渲染流程的。網絡

parsing

從網絡請求開始,最早獲取的是html文件,因此瀏覽器渲染的起點,是HTML解析器。同時HTML中引入了CSS,JS,圖片等資源,瀏覽器也會加載它們。架構

HTML文件的解析過程:

HTML文件 -stream-> HTMLDocumentParser(HTML文檔解析器)-> HTMLTreeBuilder(HTML樹構建器)-> DOM

DOM(Document Object Model) 文檔對象模型

DOM是基於HTML的倒着的樹形結構,DOM有兩個做用:

  1. 做爲Chrome的內部表示
  2. DOM樹通過v8引擎的包裝。將更新,查詢的API,暴露給js。

style

CSS樣式表的解析過程:

CSS樣式表 -> CSSParser(CSS解析器)-> 樣式規則模型(Style Rule Model)

CSS樣式是如何做用與DOM的?

根據已經解析的樣式規則(Style Rule),和瀏覽器的默認樣式,計算出每個DOM的樣式。樣式和屬性值存儲在一個巨大的ComputedStyle對象中。ComputedStyle對象是屬性和屬性值的映射。ComputedStyle對象中會掛載元素,應對應不一樣元素的不一樣樣式。

layout

在構建完DOM並完成樣式計算後,須要肯定全部元素的幾何形狀(幾何形狀所佔的區域以及座標),這些佈局信息稱爲LayoutObject對象,

佈局對象(LayoutObject)保存佈局樹中,並與DOM關聯。不一樣的節點,對應不一樣的佈局類。可是不一樣佈局類都繼承自LayoutObject這個父類。

image.png

image.png

LayoutObject對象和DOM元素並非一一對應的。好比當DOM元素的樣式是display: none時,是沒有LayoutObject對象的。

compositing update

輸入合成階段,咱們在下面講🍵

paint

根據佈局對象(LayoutObject),繪製操做會將繪製操做記錄在一個待顯示項目列表(display items list)中。

什麼是繪製操做?好比,根據佈局對象(LayoutObject)在指定區域繪製一個紅色的矩形。這就是繪製操做。

每個佈局對象(LayoutObject)對應多個待顯示項目,由於可能涉及到繪製不一樣的部分。目前只是記錄繪製操做,還沒有執行繪製操做。繪製的順序,受控於z-index屬性。

commit,tiling

提交,分割階段,咱們在下面講🍵

raster

待顯示項目列表中繪製的實際操做,是由柵格化進程執行的。

柵格化會將待顯示項,轉換爲顏色值的位圖(將圖像的信息,以像素爲單位記錄,記錄每個像素點的顏色信息rgba值)。位圖信息保存在內存中(一般是顯存中)。gpu也能夠將待顯示項目列表柵格化,咱們稱爲gpu加速。此時位圖信息還保存在顯存中,沒有輸出到屏幕上。

對於圖像信息,柵格化會對圖像進行解碼,獲取位圖信息。

柵格化的過程是經過SKIA庫調用OpenGL API完成的。

SKIA

SKIA是一個開源的圖形引擎,SKIA能夠實現柵格化,PDF輸出,GPU加速。

draw quads

draw quads階段,咱們在下面講🍵

gpu(display階段)

SKIA產生OpenGL調用,使用命令緩存區的形式,傳輸到GPU進程,GPU接受到命令緩存,產生GL調用。像素被渲染到屏幕上了。

更新渲染階段

commit(提交)-> tiling(切割)-> raster(柵格化)-> draw quads -> display(顯示到屏幕上)

渲染不是靜態的,JavaScript,用戶輸入,異步加載,動畫,滾動,縮放,都會改變渲染。從頭執行渲染流程代價會很昂貴。若是每一秒低於60fps,就會變得卡頓。

優化1: Invalidation

爲了不從頭執行整個渲染流程,經常使用的優化方法就是標記出,發生了改變的部分,複用沒有改變的部分。好比一個節點須要從新計算樣式,在下一幀的時候,只從新計算該節點的樣式。

優化2: enter: compositing 輸入合成

Chrome另外的優化手段是分層

  1. 將頁面分解成多個圖層,每個圖層能夠單獨進行柵格化。
  2. 另外單獨線程進行圖層的合成

image.png

Layers 分層

動畫,滾動,縮放,操做都會建立圖層。單獨的合成線程,會對滾動輸入操做,進行單獨處理。

while(true) {
}
複製代碼

當咱們使用js阻塞主線程時,因爲單獨的合成線程的存在,合成線程會對用戶的滾動操做進行處理,雖然主線程被阻塞可是頁面依然能夠滾動

Layers tree 圖層樹

圖層的存儲結構也是樹的形式,圖層樹間接的基於佈局樹。

image.png

compositing update 輸入合成

compositing update(輸入合成)階段發生在Layout(佈局)階段以後,Paint(繪製)階段以前。對頁面進行分層,每一個圖層被分別繪製。繪製階段存在的待顯示項目列表(display items list),其實不一樣的圖層擁有不一樣的待顯示項目列表(display items list)

image.png

commit

image.png

繪製完成後,經過同步主線程的狀態,更新合成線程圖層的狀態,最後同步回主線程

tiling

Raster會將待顯示項目列表(display items list)轉換爲位圖,可是有時候圖層會很大,Raster又是一個開銷很大的步驟,合成線程會將圖層分割爲圖塊,圖塊是Raster的基本單位。距離視口越近,會優先建立圖塊優先被柵格化。

圖塊會在單獨Raster線程中柵格化

image.png

draw

在繪製完全部圖塊以後,合成器線程將生成draw quadsdraw quads是繪製圖塊的指令,draw quads被包裝在合成器框架對象中,提交給瀏覽器進程。

display

瀏覽器進程,運行顯示合成器的組件,合成器組件調用OpenGL繪製draw quads,最後像素在用戶的屏幕上可見。

參考

相關文章
相關標籤/搜索