在上一篇當中《從輸入URL到⻚面展現,這中間發生了什麼?》最重要的過程是在頁面的渲染。這一篇咱們來梳理一下渲染流程。瀏覽器
首先咱們先熟悉頁面「三劍客」——HTML、CSS、JavaScript。HTML全稱是超文本標記語言
,俗稱標籤
;CSS全稱是層疊樣式表
,俗稱樣式
;JavaScript是瀏覽器的腳本語言,使用腳本可使內容「動」起來,簡稱JS
。性能優化
熟悉完三劍客後,來看看瀏覽器的渲染機制。它的過程較於複雜,在執行的過程中會被劃分爲多個子階段,咱們把處理一系列子階段的流程稱之爲渲染流水線
。咱們不必去熟悉每一個子階段,只需瞭解其中幾個重要的子階段過程:數據結構
先是
DOM樹
、樣式計算
、建立佈局樹
、進行分層爲分層樹
、再進入合成線程
、造成圖塊
進行光柵化
轉爲位圖
、最後瀏覽器進程根據命令DrawQuad
生成頁面顯示出來。工具
對於DOM樹相信咱們並不陌生,咱們經常聽到且在瀏覽器console裏面輸入document
能夠打印出來看獲得。 佈局
瀏覽器不只須要將HTML轉成能夠識別的DOM樹結構,並且相應的CSS樣式也須要轉化能夠識別的結構stylesheet
。其實咱們能夠在瀏覽器開發者工具console標籤處輸入document.styleSheets
,就能夠看到以下圖所示: 性能
至於樣式計算還有關於樣式屬性標準化
和層疊規則
的延展,此處就不作過多輸出,感興趣的話能夠搜索加深瞭解。優化
顧名思義,佈局就是瀏覽器按照DOM樹和styleSheets數據結構開始佈局計算,正如咱們搭建房子,把設計圖紙畫好後再動手搭建。動畫
當覺得佈局好了就能夠渲染頁面時,居然不知瀏覽器還需作下一步工做,即分層
。由於頁面中有不少複雜的效果,如一些複雜的3D變換、頁面滾動,或者使用z- indexing作z軸排序等,爲了更加方便地實現這些效果,**渲染引擎還須要爲特定的節點生成專用的圖層,並生成一棵對應的圖層樹(LayerTree)。**比如PS(PhotoShop)軟件裏面的圖層概念,正是這些圖層疊加在一塊兒構成 了最終的頁面圖像。 熟悉了圖層,再來看爲何瀏覽器還不能渲染頁面,那是由於圖層樹
須要和佈局樹
結合,也叫合成composition
。 線程
結合上圖的佈局樹和圖層樹的關係示意圖,這裏幫助筆者疏通了CSS樣式當中層疊上下文
的知識點。由於擁有層疊上下文屬性的標籤會被提高爲單獨的一層。 設計
圖層繪製(paint) 圖層樹造成後還須要圖層繪製(paint),咱們也能夠打開瀏覽器的開發者工具的「layer」標籤,選擇「document」層,來實際體驗下繪製列表,以下圖所示:
在圖中,區域1就是document的繪製列表,拖動區域2中的進度條能夠重現列表的繪製過程。
要明白柵格化,先要理解什麼是圖塊和位圖。首先圖塊(tile)是渲染進程即瀏覽器內核當中的合成線程將圖層劃分爲大小512x512或者256x256的區塊。
其次位圖則是柵格化的過程:合成線程會按照視口附近的圖塊來優先生成位圖,實際生成位圖的操做是由柵格化來執行的,將圖塊轉換爲位圖。
一旦全部圖塊都被光柵化,合成線程就會生成一個繪製圖塊的命令——「DrawQuad」,而後將該命令提交給瀏覽器進程處理,最終將頁面display呈現出來。
至此已經分析完整個渲染流程,從HTML到DOM、樣式計算、佈局、圖層、繪製、光柵化、合成和顯示。下面一張圖是總結下這整個渲染流程:
結合上圖,一個完整的渲染流程大體可總結爲以下:
DOM樹
結構。styleSheets
,計算出DOM節點的樣式。佈局樹
,並計算元素的佈局信息。分層樹
。繪製列表
,並將其提交到合成線程。圖塊
,並在光柵化線程池
中將圖塊轉換成位圖。DrawQuad
給瀏覽器進程。顯示
到顯示器上。當咱們把瀏覽器內核工做流程熟悉後再回過頭看性能優化當中經常提到的「重排」、「重繪」和「合成」,相信就能夠理解更加透徹一點了。
重排是更新了元素的幾何屬性,例如改變了元素的寬高,會觸發瀏覽器從新渲染流程,解析以後的一系列子階段,因此說重排會致使開銷最大。
重繪是更新元素的繪製屬性,例如元素的背景色,不會引發元素的幾何位置變化,就直接進入了繪製階段,而後執行以後的一系列子階段。因此相對重排來講,執行效率會高一些,由於省去了佈局計算和分層階段。
合成是改了元素的既不佈局也不繪製的屬性,例如transform實現動畫效果,避開重排和重繪階段,直接在非主線程上 執行合成動畫操做。這樣的效率是最高的,由於是在非主線程上合成,並無佔用主線程的資源,另外也避開了佈局和繪製兩個子階段,因此相對於重繪和重排,合成能大大提高繪製效率。
經過整理來自極客時間課程《瀏覽器工做原理與實踐》筆記,對瀏覽器的渲染進程瞭解更加深刻,對於頁面從URL到展示的過程瞭然於胸,強迫本身作筆記仍是蠻有收穫滴~但願筆記能夠幫助到你們。