08.29 極鏈科技學社:從輸入URL到頁面加載發生了什麼?

作者 | 極鏈科技Video++ 整理 | 包包

最近經常可以看到一個前端面試題,就是從輸入URL到頁面加載,這個過程會發生沒什麼。其實,這是一個非常開放性的問題,曾看到一個調侃,如果面試官敢問這個問題,他可以用一個下午把整個流程講一遍,從硬件方面鍵盤工作的原理到網路的傳輸都說一遍。網上大部分的回答主要是關於DNS解析和到服務端之前的過程。最近,看到一篇關於瀏覽器是如何工作的文章,所以我想聊下,這個問題的後半部分,就是當靜態資源傳輸到瀏覽器之後,會經過哪些部分,又做了哪些處理。

這裡一個主要的部分就是呈現引擎。呈現引擎主要負責解析HTML和CSS,並將內容轉化為肉眼可見的UI。

市場上每家瀏覽器都使用略微不同的引擎,IE使用自己開發的Trident,火狐使用Gecko,Safari是使用開源的Webkit,Chrome和Opera fork了webkit,並在此基礎上開發了Blink。每個呈現引擎在構建DOM樹的方式和流程都有些不同,也導致同一份代碼,在不同的瀏覽器上會有不用的顯示效果。下面,是以WebKit為例子,看下他們的流程是什麼樣子的。

當瀏覽器遇到靜態資源

HTML,CSS這些靜態資源,千里迢迢經過各個環節來到瀏覽器的時候,主要經歷四個基本步驟

解析HTML和CSS。HTML的解析過程,會把HTML標籤按照順序,組成內容樹。這種解析並不是轉化為機器代碼,而是轉換成另外一種格式保存這些數據。

呈現樹的構建。呈現樹是內容樹和樣式規則的結合。簡單總結就是HTML和CSS通過解析,轉換為樹狀格式,方便瀏覽器進行渲染。

佈局。來到這裡,瀏覽器會遞歸的對每個節點計算出位置和大小信息。

繪製。在這一步,真正的UI才會被繪製在瀏覽器上面,供用戶瀏覽和使用。

每個瀏覽器對這四個步驟都會有不同的實現,下圖為WebKit的實現流程。

極鏈科技學社:從輸入URL到頁面加載發生了什麼?

圖1:Webkit 呈現引擎的流程。

如圖所示,HTML和CSS首先會通過兩個解析器,分別為HTML Parser(HTML解析器)和CSS Parser(CSS 解析器)。解析過程在呈現引擎裡面是非常重要的一步。

可以通過下面一個例子,簡單理解這個過程。

2 + (3 - 1)

假設我們要去教一個幼兒園的小朋友上面的計算方式。我們可能需要以下幾步去開始。

學單詞。比如,首先知道這些數字,加號,減號和括號是什麼意思。

學規則。比如,括號內的級別優先。運算順序從左及右。

同理,解析器在面對HTML,CSS和JavaScript的時候也需要去定義單詞和規則,這裡的單詞量更大,規則更為複雜。也有了更學術的名字,詞法分析(學單詞)和語法分析(學語法)。

詞法分析將無關內容剔除,比如空格和換行,提取有效內容並分割成更小的單位,如具體的單詞。這就相當於告訴計算機每個單詞的意思。認識了單詞之後,還需要學習語法,才能懂的上面公式的結果。語法分析會根據定義的規則去構建並學習單詞之間的關係,最終明白了整個句子的意思。在這個過程中還會碰到很多問題,比如有些HTML寫的並不是很規範或者要兼容舊的HTML規範。HTML和CSS經過解析之後,格式會經過處理,變成了樹狀結構,有一定的層級關係。相當於計算機通過我們定義的單詞和語法,理解了我們的代碼之後,經過自己的理解轉換成一種更方便計算機處理的方式 --- 呈現樹。

呈現樹是按照用戶肉眼可見的元素排列而成,它和我們熟悉的DOM樹很相似但又有些差別,比如DOM裡面有些元素不會和呈現樹裡的元素一一相對應,如head標籤,又或display為none的元素,這些元素是不會被展示出來,所以並沒有被納入到呈現樹中。所以呈現樹只會保留所有用戶可見的元素,用來方便接下來的構建和渲染。

在呈現樹中,因為是一種樹狀結構,我們可以看到每個節點之間的關係,可以明顯的找出上下級關係,這個上下級關係,也是最終渲染的關係,從裡面可以看出是否有子節點或者同級節點。樣式經過解析,也會以另外一種更加節省內存的結構儲存下來。樣式的規則會附加在內容樹上面從而組成了最終的呈現樹。

有了呈現樹,瀏覽器可以依次計算出具體節點的位置和大小。這個過程是個遞歸的過程。從頂端開始,根據從左到右,由上及下的開始計算,直到所有的節點的信息都計算完成。為了應對局部的小變化而導致整體的重新計算,瀏覽器會把變化的部分標記為dirty,或者children are dirty,用來表示本節點或者子節點需要重新計算。剩下的工作就是把所有計算的內容,渲染到頁面上。同樣,渲染的過程也會分局部和全局渲染。

整個的渲染過程是單線程同步運行。解析器在解析HTML的過程中,如果碰到


分享到:


相關文章: