問我Chrome瀏覽器的渲染原理(6000字長文)

前言

對於HTML,css和JavaScript是如何變成頁面的,這個問題你瞭解過嗎?瀏覽器究竟在背後都作了些什麼事情呢?讓咱們去了解瀏覽器的渲染原理,是通往更深層次的開發必不可少的事情,能讓咱們更深層次,多角度的去考慮性能優化等問題。css

HTML,css,JavaScript數據通過中間渲染模塊的處理,最終顯示在頁面上(其中HTML超文本標記語言,CSS層疊樣式表,JS爲JavaScript,你們通常都知道是什麼,寫過網頁的朋友,學習者大都知道的)。html

  • HTML的內容是由標記和文本組成
  • CSS稱爲層疊樣式表,是由選擇器和屬性組成
  • JS是可使網頁的內容「動」起來

有人說渲染流程能夠分爲:構建DOM樹,樣式計算,佈局階段,分層,繪製,分塊,光柵化和合成等。其中瀏覽器複習一下,它是多線程的的,js是單線程的,JS在瀏覽器中,它能夠是多線程的。html5

下面圍繞瀏覽器渲染原理話題開始描述,爲何要了解瀏覽器渲染頁面機制呢?。面試

瀏覽器渲染原理

首先,JavaScript引擎是基於事件驅動單線程執行的,渲染線程負責渲染瀏覽器界面,可是GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI的更新也會被保存在一個隊列中,等到JS引擎空閒時纔有機會被執行。數據庫

那麼什麼是DOCTYPE以及做用呢

DTD,document type definition, 文檔類型定義,是一系列的語法規則,用來定義XML或(x)HTML的文件類型。瀏覽器會使用它來判斷文檔類型,決定使用何種協議來解析,以及切換瀏覽器模式。後端

DOCTYPE是用來聲明文檔類型和DTD規範的,一個主要的用途即是文件的合法性驗證。若是文件代碼不合法,那麼瀏覽器解析時便會出一些差錯。瀏覽器

下圖爲瀏覽器的渲染過程圖:緩存

重排Reflow

重排的定義:DOM結構中的各個元素都有本身的盒子模型,這些都須要瀏覽器根據各類樣式來計算並根據計算結果將元素放到它該出現的位置,這個過程稱之爲reflow.

觸發Reflow狀況性能優化

  • 當你增長,刪除,修改Dom節點時會致使Reflow或Repaint
  • 當你移動DOM的位置,或是搞個動畫的時候
  • 當你修改CSS樣式的時候
  • 當你Resize窗口的時候,或是滾動的時候
  • 當你修改網頁的默認字體時

重繪Repaint

重繪的定義,當各類盒子的位置,大小以及其餘屬性,例如顏色,字體大小等都肯定下來後,瀏覽器因而便把這些元素都按照各自的特性繪製了一遍,因而頁面的內容出現了,這個過程稱爲repaint。

觸發Repaint狀況服務器

  • DOM改動
  • CSS改動

講到這裏,下面來細分說一下吧!

簡單介紹一下瀏覽器的工做原理

  1. 瞭解瀏覽器

目前使用的主流的瀏覽器:Internet Explorer,Firefox,Safari,Chrome瀏覽器,Opera。讓咱們看看瀏覽器統計數據的佔比:

讓你說說瀏覽器的主要功能:

就是向服務器發出請求,在瀏覽器窗口中展現您選擇的網絡資源,資源通常指HTML文檔,能夠是PDF,圖片或其餘的類型。資源的位置由用戶使用URI(在電腦術語中,統一資源標識符(Uniform Resource Identifier,URI)是一個用於標識某一互聯網資源名稱的字符串)

  1. 瀏覽器的結構
  • 用戶界面:包括地址欄,前進、後退按鈕,書籤菜單等。
  • 瀏覽器引擎:在用戶界面和呈現引擎之間傳送指令。
  • 呈現引擎:負責顯示請求的內容。
  • 網絡:用於網絡調用,好比HTTP請求;其接口與平臺無關,併爲全部平臺提供底層實現。
  • 用戶界面後端:用於繪製基本的窗口小部件,好比組合框和窗口。其公開了與平臺無關的通用接口,而在底層使用操做系統的用戶界面方法。
  • JavaScript解釋器:用於解析和執行JavaScript代碼。
  • 數據存儲:這是持久層。瀏覽器須要在硬盤上保存各類數據,例如Cookie。新的HTML規範定義了「網絡數據庫」,這是一個完整的瀏覽器內數據庫。

注意:Chrome瀏覽器的每一個標籤頁都分別對應一個呈現引擎實例,每一個標籤頁都是一個獨立的進程。

  1. 呈現引擎

呈現引擎的做用是「呈現」,用於在瀏覽器的屏幕上顯示請求的內容。

通常狀況下,呈現引擎可顯示HTML和xml文檔與圖片,經過插件或瀏覽器擴展程序,能夠顯示其餘類型的內容。瀏覽器(Firefox,Chrome瀏覽器和Safari)是基於兩種呈現引擎構建的。

Firefox使用的是Gecko,而Safari和Chrome瀏覽器使用的是WebKit(WebKit 是一種開放源代碼呈現引擎)。

  1. 主流程

呈現引擎一開始會從網絡層獲取請求文檔的內容,其大小通常限制在8000個塊之內。

呈現引擎將開始解析HTML文檔,並將各標記逐個轉化成「內容樹」上的DOM節點。同時也會解析外部CSS文件以及樣式元素中的樣式數據。呈現樹構建完後,會進入「佈局」處理階段,也就是爲每一個節點分配一個應出如今屏幕上的確切座標。

  1. 解析

解析是呈現引擎中重要的環境,什麼是解析呢?

解析文檔是指將文檔轉化成爲有意義的結構,可讓代碼理解和使用的結構。解析獲得的結構一般是表明了文檔結構的節點樹,它稱爲解析樹或者語法樹。

  1. 語法

解析是以文檔所遵循的語法規則爲基礎的。解析的過程分爲兩個子過程:詞法分析和語法分析。

什麼是詞法分析呢?

詞法分析是將輸入內容分割成大量標記的過程,標記(語言中的詞彙),構成內容的單位。相等於語言中的單詞。

什麼是語法分析呢?

語法分析是應用語言的語法規則的過程。

so,解析器通常解析工做分兩個組件處理,爲詞法分析器(負責將輸入內容分解成一個個有效標記),解析器負責根據語言的語法規則來分析文檔的結構,來構建解析樹。

從源文檔到解析樹:Document->Lexical Analysis->Syntax Analysis->Parse Tree

解析是一個迭代的過程。

是這樣的,解析器會向詞法分析器請求一個新標記,並嘗試將其與某條語法規則進行匹配。若是匹配規則,解析器就會將對應與該標記的節點添加到解析樹中,而後繼續下一個。

可是若是沒有匹配的規則,解析器會將標記存儲到內部,繼續請求標記,直到可與之匹配的規則,可是若是沒有直到的話,就會引起異常(文檔無效,包含語法錯誤等)。

  1. 翻譯

解析一般是在翻譯的過程當中,而翻譯是將輸入的文檔轉換爲另外一種形式,如編譯器將源代碼編譯成機器代碼,流程是將源代碼解析成解析樹,將解析樹翻譯成機器代碼文檔。

編譯流程:Source Code -> Parsing->Parse Tree -> Translation -> Machine Code
  1. 解析器類型

兩種基本的解析器類型:自上而下解析器,自下而上解析器

自上而下就是: 解析器從語法的高層結構出發,嘗試從中找到匹配的結構。

自下而上就是: 解析器從低層規則出發,將輸入內容逐步轉化爲語法規則,直至知足高層規則。

你知道一種工具叫解析器生成器嗎,它可以幫助你生成解析器,你只要向它提供你所使用的語言的語法,即詞彙和語法規則,而後就會生成相應的解析器。

你暈了嗎?能夠點擊這裏查看:瀏覽器的工做原理:新式網絡瀏覽器幕後揭祕
https://www.html5rocks.com/zh...

渲染機制

瀏覽器從接收到頁面開始到頁面顯示,這整個過程當中的全部步驟,稱 關鍵渲染路徑 ,通常分爲兩步:頁面內容加載完成和頁面資源完成,分別對應於DOMContentLoaded和Load

關鍵:網頁的渲染過程以下,包含頁面加載和頁面渲染兩個過程。

頁面加載過程是,從服務器請求資源並構建DOM樹的過程,網頁渲染過程指的是經過DOM樹渲染出視圖內容。

DOM + CSS -> Render Tree

複習一下整個關鍵渲染包括:

  • 解析HTML,生成DOM樹(DOM)
  • 解析CSS,生成CSSOM樹
  • 將DOM和CSSOM合併,生成渲染樹(Rendere-Tree)
  • 計算渲染樹的佈局Layout
  • 將佈局渲染到屏幕上Paint

那麼要問了,爲何要了解瀏覽器渲染頁面機制呢?

瞭解渲染機制,主要仍是爲了性能的優化:

瞭解瀏覽器如何進行加載,引用外部樣式文件,JS文件時,將它們放到合適的位置,是瀏覽器最快的速度讓文件加載完畢;瞭解瀏覽器如何進行解析,選擇最優的寫法,構建DOM結構,組織CSS選擇器的時候,是爲了提升瀏覽器的解析速率;瞭解瀏覽器如何進行渲染,是能夠減小「重繪」,「從新佈局」的消耗。

那麼上面一直說了解渲染機制,出現的幾個基本概念,這裏先弄明白:

  • DOM: Document Object Model,瀏覽器將HTML解析成樹形的數據結構
  • CSSOM: CSS Object Model,瀏覽器將CSS解析成樹形的數據結構
  • Render Tree: DOM和CSSOM合併生成Render Tree
  • Layout: 計算出Render Tree每一個節點的具體位置
  • Painting: 經過顯卡,將Layout後的節點內容分別呈現到屏幕上

說說瀏覽器頁面渲染:

  • 第一步:在CSS資源尚未請求回來以前,先生成DOM樹;
  • 第二步:當全部的CSS請求回來以後,瀏覽器按照CSS的導入順序,依次進行渲染,最後生成CSSOM樹;
  • 第三步:把DOM樹和CSSOM樹結合在一塊兒,生成有樣式,有結構的RENDER TREE渲染樹;
  • 最後一步:瀏覽器按照渲染樹,在頁面中進行渲染和解析

來源於知乎的渲染引擎及關鍵渲染路徑

因爲渲染機制過於複雜,渲染模塊在在執行過程當中劃分了不少階段,經過《瀏覽器工做原理與實踐》-渲染流程上分:構建DOM樹,樣式計算,佈局階段;渲染流程下分:分層,圖層繪製,柵格化(raster)操做,合成和顯示。

整個渲染流程,從HTML到DOM、樣式計算、佈局、圖層、繪製、光柵化、合成和顯示。

面試一問:爲何要構建DOM樹?

答:由於瀏覽器不能直接理解和使用HTML,so,須要將HTML轉換爲瀏覽器可以理解的結構,便是DOM樹(樹結構通常都瞭解了的)。

爲了瞭解完整的DOM樹結構,能夠打開Chrome的「開發者工具」,或按F12,如圖下:

接下來要讓DOM節點擁有正確的樣式,這就須要樣式計算了。

樣式計算的目的是爲了計算出DOM節點中每一個元素的具體樣式:三步走

  • 把CSS轉換爲瀏覽器可以理解的結構
  • 轉換樣式表中的屬性值,使其標準化
  • 計算出DOM樹中每一個節點的具體樣式(涉及到CSS的繼承規則和層疊規則)
當渲染引擎接收到CSS文本時,會執行一個轉換操做,將CSS文本轉換爲瀏覽器能夠理解的結構——styleSheets。屬性值標準化的過程:將全部值轉換爲渲染引擎容易理解的、標準化的計算值。

DOM元素最終計算的樣式如圖:

佈局階段

佈局:計算出DOM樹中可見元素的幾何位置,第一建立佈局樹(構建一棵只包含可見元素佈局樹),第二佈局計算。

面試問題:CSS加載會阻塞頁面顯示嗎?

  • css加載不會阻塞DOM樹的解析
  • css加載會阻塞DOM樹的渲染
  • css加載會阻塞後面js語句的執行

so,爲了不讓用戶看到長時間的白屏時間,應該提升css的加載速度。

爲了防止css阻塞,引發頁面白屏,能夠提升頁面加載速度

  • 使用cdn
  • 對css進行壓縮
  • 合理利用緩存
  • 減小http請求,將多個css文件合併

面試問題:下載CSS文件阻塞了,會阻塞DOM樹的合成嗎?會阻塞頁面的顯示嗎?

說了DOM生成、樣式計算和佈局三個階段,接下來講說後面的階段。

說說分層:渲染引擎給頁面分了不少圖層,這些圖層按照必定順序疊加在一塊兒,就造成了最終的頁面。完成圖層樹的構建後,渲染引擎會對圖層樹中的每一個圖層進行繪製,爲圖層繪製。而後進行柵格化(raster)操做(繪製列表只是用來記錄繪製順序和繪製指令的列表,而實際上繪製操做是由渲染引擎中的合成線程來完成的),最後合成與顯示。

找一張總體的流程圖以下:

頁面渲染機制圖以下:

渲染過程圖以下:

瀏覽器渲染過程以下:

瀏覽器解析的三個東西流程圖以下:

一是HTML/SVG/XHTML

二是CSS

三是Javascript腳本

這裏重要要說(從新說一下)兩個概念迴流和重繪

當render tree中的一部分由於元素的規模尺寸,佈局,隱藏等改變而須要從新構建。這就稱爲迴流(reflow)。

每一個頁面至少須要一次迴流,就是在頁面第一次加載的時候。

在迴流的時候,瀏覽器會使渲染樹中受到影響的部分失效,並從新構造這部分渲染樹,完成迴流後,瀏覽器會從新繪製受影響的部分到屏幕中,該過程成爲重繪。

當render tree中的一些元素須要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,好比background-color。就叫稱爲重繪。

本篇文章的最後,留下一些面試題:爲何減小重繪、重排能優化Web性能嗎?如何能減小重繪、重排呢?

總結

以上就是今天要講的內容,本文僅僅簡單介紹了Chrome瀏覽器的渲染原理流程,感謝閱讀,若是你以爲這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友。

相關文章
相關標籤/搜索