學習瀏覽器渲染原理是爲了可以提升頁面性能,避免無心間對性能形成損耗。而且面試過程當中答得比較好的話... 雖然我仍是一名在校生...html
本文討論的是基於WebKit內核(Chrome和Safair)渲染引擎的內容,渲染引擎在不一樣內核實現的瀏覽器中存在差別。node
從服務端接受到數據後,瀏覽器將這些字節碼轉變成渲染的像素這一過程,都經歷了什麼?瞭解其中的過程,有助於咱們寫出更加精幹的代碼,這些過程簡稱爲關鍵選渲染路徑。經過優化關鍵渲染路徑,可以爲構建高性能交互式操做打下基礎。 瀏覽器進行渲染頁面前,須要先構建出DOM樹和CSSOM樹,所以咱們須要確保儘快將HTML代碼和CSS代碼提供給瀏覽器。面試
打開網頁,瀏覽器首先經過網絡請求對應的HTML文件,因爲計算機硬件是不識別字符串的(HTML、CSS和JS 文件),因此在網絡傳輸過程當中轉化成0和1的字節數據。當瀏覽器接受收到這些字節數據後,它會將字節數據轉化成字符串(characters)。瀏覽器
瀏覽器將轉換成的字符串,按照W3C的標準規定轉化成各類token(令牌),例如<html>
標籤等其餘尖括號內的字符串,每一個token都具備特殊含義以及一組規則。bash
當結束標記化後,這些token會當即轉化爲Node,同時這些Node會根據不一樣Node之間的關係構成一顆DOM樹。整個流程的最終輸出是咱們訪問頁面的文檔對象模型 (DOM),瀏覽器對頁面進行的進一步處理都會用到它。 markdown
補充:在node轉化爲DOM樹這一過程當中,是根據每一個token之間的層級嵌套關係,進而肯定DOM的樹形結構。而且DOM樹的構建是逐步逐步構建的,而不是在整個過程最後構建。 以上就是瀏覽器從網絡中接收到HTML文件後一系列的轉換過程。網絡
在解析HTML文件構建DOM樹時,還會遇到CSS和JS文件,這時候瀏覽器也會去下載並解析這些文件。但請記住在這過程當中若是執行了JS代碼,會暫停DOM樹的構建,目的是保證可以正確的構建DOM樹(JavaScript代碼可以修改DOM節點)數據結構
在瀏覽器構建DOM樹時,在文檔的head部分會遇到link標記,該標記引用一個外部CSS樣式表,因爲預測到須要利用該文件來進行渲染頁面,他會當即發出對該資源的請求。 與處理HTML時同樣,咱們須要將收到的CSS文件轉換成某種瀏覽器可以理解和處理的東西。所以咱們會重複建立DOM樹的過程來建立CSSOM樹。最終造成一顆CSSOM樹結構。 佈局
這一過程當中,瀏覽器會肯定每個節點的樣式,此過程實際是比較消耗資源的。由於在設置樣式的時候能夠直接設置樣式,也能夠經過繼承得到,因此瀏覽器就得遞歸CSSOM樹。最終肯定某元素的樣式。 舉例:性能
<div>
<a> <span></span> </a>
</div>
<style>
span {
color: red;
}
div > a > span {
color: red;
}
</style>
複製代碼
對於第一種狀況,瀏覽器須要找到頁面中全部的span標籤而後設置顏色。 對於第二種狀況,瀏覽器首先須要找到全部的span標籤,而後找到span標籤上的a標籤,最後找到div標籤,肯定知足條件的span元素後設置顏色,這樣的遞歸過程很複雜。 因此要避免寫過於具體的CSS選擇器,對於HTML來講儘可能少添加無心義的標籤,保持層級扁平化。
CSSOM樹和DOM樹合併成渲染樹。但它們都是獨立的對象,分別用於網羅文檔不一樣方面的信息:一個描述內容,另外一個則是描述須要對文檔應用的樣式規則。
但是咱們應該如何合併兩顆樹呢?並讓瀏覽器屏幕上渲染像素呢?
1.從DOM樹的根節點開始遍歷每一個可見的節點
2.對於每一個可見的節點爲他們找到匹配的CSSOM規則並應用他們。 最終輸出的渲染樹包含了屏幕上的全部可見內容及其樣式信息。有了渲染樹,咱們就能夠進入「佈局」階段。
到目前爲止,咱們已經肯定了哪些節點是可見的,以及通過計算後的樣式信息,可是咱們並無計算他們在設備視口中的準確位置和大小。這就是在佈局階段須要解決的,同時也稱爲自動重排 當瀏覽器通過佈局計算後,肯定了每一個元素的大小以及精確的位置,並將全部測量值都轉換爲屏幕上的絕對像素後,將會把這些信息傳遞給最後一個階段,繪製階段。
上述步驟都須要瀏覽器完成大量工做,因此至關耗時。執行渲染樹構建、佈局和繪製所需的時間將取決於文檔大小、應用的樣式,以及運行文檔的設備:文檔越大,瀏覽器須要完成的工做就越多;樣式越複雜,繪製須要的時間就越長。 咱們提及來可能很簡單,實際上瀏覽器卻須要完成至關多的工做。若是 DOM樹 或 CSSOM樹 被修改,只能再執行一遍以上全部步驟,以肯定哪些像素須要在屏幕上進行從新渲染。
概述一下瀏覽器所經歷的過程: