瀏覽器頁面的渲染流程

在上一篇當中《從輸入URL到⻚面展現,這中間發生了什麼?》最重要的過程是在頁面的渲染。這一篇咱們來梳理一下渲染流程。瀏覽器

首先咱們先熟悉頁面「三劍客」——HTML、CSS、JavaScript。HTML全稱是超文本標記語言,俗稱標籤;CSS全稱是層疊樣式表,俗稱樣式;JavaScript是瀏覽器的腳本語言,使用腳本可使內容「動」起來,簡稱JS性能優化

熟悉完三劍客後,來看看瀏覽器的渲染機制。它的過程較於複雜,在執行的過程中會被劃分爲多個子階段,咱們把處理一系列子階段的流程稱之爲渲染流水線。咱們不必去熟悉每一個子階段,只需瞭解其中幾個重要的子階段過程:數據結構

先是DOM樹樣式計算、建立佈局樹、進行分層爲分層樹、再進入合成線程、造成圖塊進行光柵化轉爲位圖、最後瀏覽器進程根據命令DrawQuad生成頁面顯示出來。工具

DOM樹

對於DOM樹相信咱們並不陌生,咱們經常聽到且在瀏覽器console裏面輸入document能夠打印出來看獲得。 佈局

DOM數構建過程示意圖

樣式計算(Recalculate Style)

瀏覽器不只須要將HTML轉成能夠識別的DOM樹結構,並且相應的CSS樣式也須要轉化能夠識別的結構stylesheet。其實咱們能夠在瀏覽器開發者工具console標籤處輸入document.styleSheets,就能夠看到以下圖所示: 性能

至於樣式計算還有關於樣式屬性標準化層疊規則的延展,此處就不作過多輸出,感興趣的話能夠搜索加深瞭解。優化

佈局階段(Layout)

顧名思義,佈局就是瀏覽器按照DOM樹和styleSheets數據結構開始佈局計算,正如咱們搭建房子,把設計圖紙畫好後再動手搭建。動畫

分層-圖層樹(LayerTree)

當覺得佈局好了就能夠渲染頁面時,居然不知瀏覽器還需作下一步工做,即分層。由於頁面中有不少複雜的效果,如一些複雜的3D變換、頁面滾動,或者使用z- indexing作z軸排序等,爲了更加方便地實現這些效果,**渲染引擎還須要爲特定的節點生成專用的圖層,並生成一棵對應的圖層樹(LayerTree)。**比如PS(PhotoShop)軟件裏面的圖層概念,正是這些圖層疊加在一塊兒構成 了最終的頁面圖像。 熟悉了圖層,再來看爲何瀏覽器還不能渲染頁面,那是由於圖層樹須要和佈局樹結合,也叫合成composition線程

佈局樹和圖層樹關係示意圖

結合上圖的佈局樹和圖層樹的關係示意圖,這裏幫助筆者疏通了CSS樣式當中層疊上下文的知識點。由於擁有層疊上下文屬性的標籤會被提高爲單獨的一層設計

圖層繪製(paint) 圖層樹造成後還須要圖層繪製(paint),咱們也能夠打開瀏覽器的開發者工具的「layer」標籤,選擇「document」層,來實際體驗下繪製列表,以下圖所示:

在圖中,區域1就是document的繪製列表,拖動區域2中的進度條能夠重現列表的繪製過程。

柵格化(raster)

要明白柵格化,先要理解什麼是圖塊和位圖。首先圖塊(tile)是渲染進程即瀏覽器內核當中的合成線程將圖層劃分爲大小512x512或者256x256的區塊

其次位圖則是柵格化的過程:合成線程會按照視口附近的圖塊來優先生成位圖,實際生成位圖的操做是由柵格化來執行的,將圖塊轉換爲位圖

顯示(DrawQuad)

一旦全部圖塊都被光柵化,合成線程就會生成一個繪製圖塊的命令——「DrawQuad」,而後將該命令提交給瀏覽器進程處理,最終將頁面display呈現出來。

渲染流水線大總結

至此已經分析完整個渲染流程,從HTML到DOM、樣式計算、佈局、圖層、繪製、光柵化、合成和顯示。下面一張圖是總結下這整個渲染流程:

結合上圖,一個完整的渲染流程大體可總結爲以下:

  1. 渲染進程將HTML內容轉換爲可以讀懂的DOM樹結構。
  2. 渲染引擎將CSS樣式錶轉化爲瀏覽器能夠理解的styleSheets,計算出DOM節點的樣式。
  3. 建立佈局樹,並計算元素的佈局信息。
  4. 對佈局樹進行分層,並生成分層樹
  5. 爲每一個圖層生成繪製列表,並將其提交到合成線程。
  6. 合成線程將圖層分紅圖塊,並在光柵化線程池中將圖塊轉換成位圖。
  7. 合成線程發送繪製圖塊命令DrawQuad給瀏覽器進程。
  8. 瀏覽器進程根據DrawQuad消息生成頁面,並顯示到顯示器上。

當咱們把瀏覽器內核工做流程熟悉後再回過頭看性能優化當中經常提到的「重排」、「重繪」和「合成」,相信就能夠理解更加透徹一點了。

重排是更新了元素的幾何屬性,例如改變了元素的寬高,會觸發瀏覽器從新渲染流程,解析以後的一系列子階段,因此說重排會致使開銷最大

重繪是更新元素的繪製屬性,例如元素的背景色,不會引發元素的幾何位置變化,就直接進入了繪製階段,而後執行以後的一系列子階段。因此相對重排來講,執行效率會高一些,由於省去了佈局計算和分層階段。

合成是改了元素的既不佈局也不繪製的屬性,例如transform實現動畫效果,避開重排和重繪階段,直接在非主線程上 執行合成動畫操做。這樣的效率是最高的,由於是在非主線程上合成,並無佔用主線程的資源,另外也避開了佈局和繪製兩個子階段,因此相對於重繪和重排,合成能大大提高繪製效率。

經過整理來自極客時間課程《瀏覽器工做原理與實踐》筆記,對瀏覽器的渲染進程瞭解更加深刻,對於頁面從URL到展示的過程瞭然於胸,強迫本身作筆記仍是蠻有收穫滴~但願筆記能夠幫助到你們。

相關文章
相關標籤/搜索