用戶在瀏覽器的地址欄輸入URL,期待的結果就是可見的圖像,包含了用戶想得到的信息。那麼從URL到圖像,需要經過哪些步驟呢?瀏覽器是如何獲取、解析、呈現這些信息的?
通過前面的分析可以知道,在渲染過程中會產生DOM樹,內部表示,RenderObject和RenderLayer樹,虛擬的繪製上下文,最終得到圖像。用到的模塊包括HTML解釋器、CSS解釋器、JS引擎以及佈局和繪製模塊。
對數據的流向分析,然後這一渲染過程分成三個階段,階段之間的界限並不是那麼清晰,對動態網頁往往需要重複渲染。第一階段是從網頁的URL到構建DOM樹,第二階段是DOM樹到構建完WebKit的繪圖上下文,第三階段是從繪圖上下文到生成最終圖像。
第一階段具體過程:
- 1、用戶輸入URL,瀏覽器調用資源加載模塊加載URL對應的網頁文檔;
- 2、加載模塊依賴網絡模塊建立與服務器的連接,發送請求並接受答覆;
- 3、WebKit接收到各種網頁或者資源的數據,有些資源需要同步或者異步獲取;
- 4、將接收到的網頁交給HTML解釋器解析,解析成一系列的Token;
- 5、HTML解釋將這些Token建立節點,構建DOM樹;
- 6、如果節點是JavaScript代碼的話,交給JS引擎處理;
- 7、JS有可能修改已經建立的DOM樹;
- 8、解析過程中可能會需要加載其他資源,如CSS樣式表、圖片、視頻等,就會調用加載器再次加載這些資源。
在這個過程中,渲染引擎會發出兩個事件“DOMContentLoaded”和“load”,它們分別是在構建好DOM樹後,以及構建好DOM樹併網頁所依賴資源都加載完成後發出。
驗證這一個過程,建立如下html文檔:
<html>
<head>
<style type="text/css">
img {width: 200px;}
</style>
<title> This is a simple case.</title>
</head>
<body>
<img src="qq.jpg"></img>
<div> Hello World! </div>
<script type="text/javascript">
window.onload = function(){
console.log("window.onload()");
}
console.log("It's me.");
</script>
</body>
</html>
此html文檔包含一個<img>,在解析過程中遇到圖像資源,需要調用加載器加載,但是不影響DOM樹的建立。
用chrome瀏覽器打開上述網頁,然後點右鍵,選擇審查元素,再點擊NetWork,可以看到發出事件的時間。
上面的圖清晰的表明觸發的事件,以及觸發的時間。最下面一行文字表明有兩個請求,分別是DOMContentLoaded在68ms和load在88ms。和分析的一樣,這個文檔包含兩個資源,一個是html文檔一個是圖片資源,它們的加載時間不同,導致觸發的兩個事件的時間有間隔。右側的豎線表明資源加載全部結束,DOM構建完成,渲染的第一階段也結束了。