轉自:WebKit如何載入web頁面
原文連結:http://webkit.org/blog/1188/how-webkit-loads-a-web-page/
在WebKit能夠渲染web頁面之前,它必須從網路載入頁面和子資源。從web載入資源涉及到許多層,本文將集中於WebCore,即WebKit的主要渲染組件,如何參與載入過程。
WebKit包含兩條載入管道,一個用於載入文檔到架構(frame),另一個用於載入子資源(片和指令碼)。總結了兩條管道涉及的主要對象:
載入架構(Frame)
FrameLoader負責載入文檔到架構,當您點選連結的時候,FrameLoader開始建立一個新的處在“策略(policy)”狀態的
DocumentLoader對象,在該狀態下等待webkit客戶決定如何處理本次載入。通常客戶指示FrameLoader將載入當作導航
(navigator)(而不是阻塞式載入)。
一旦客戶指示FrameLoader將載入當作導航,FrameLoader將DocumentLoader遷移到"臨時(provision)"狀態,啟動網路請求,並等待以判斷網路請求的結果是下載還是一個新的文檔。
接著,DocumentLoader建立MainResourceLoader,它的任務是通過ResourceHandle介面和平台相關網路程式庫
互動。將MainResourceLoader從DocumentLoader分離出來有兩個目的:(1)
MainResourceLoader將DocumentLoader從處理ResourceHandle回調的細節隔離開來。(2)
MainResourceLoader的生命週期與DocumentLoader的生命週期(與Document緊密關聯)分離。
一旦載入系統從網路接收到足夠的資訊,判斷出接收的資源確實表示一份文檔,FrameLoader將DocumentLoader遷移到"已提交(committed)"狀態,Frame開始顯示新的文檔。
載入子資源(Subresource)
當然,顯示一個web頁面需要的不僅僅是組成文檔的HTML,還需要載入映像、指令碼以及其它文檔引用到的子資源。DocLoader就是負責載入這些子資源的(注意,雖然DocumentLoader和DocLoader名稱上相似,但它們的職責卻大不相同)。
我們以載入圖片為例。要載入一個映像,DocLoader首先檢查Cache是否在記憶體中已經有一份映像的副本(如CachedImage對象)。
如果Cache中已經存在,DocLoader會立即響應。甚至進一步提高效率,Cache總是將解碼過的映像放在顯存,這樣WebKit就不需要對同一
映像做兩次解碼。
如果映像不在Cache中,Cache將建立一個新的CacheImage對象表示該映像。CacheImage對象將要求“Loader“對象創
建SubresourceLoader來啟動網路請求。SubresourceLoader在子資源載入管道中所起的作用和
MainResourceLoader在主資源載入管道中所起的作用類似,都是直接和ResourceHanle的平台相關介面互動。
需改進的地方
WebKit載入管道還有許多可以改進的地方。FrameLoader過分複雜,參與了過多的任務而不僅僅是載入載入架構。例
如,FrameLoader有幾個稍微不同的"load"方法,這比較讓人費解,它們負責建立視窗,這似乎和載入架構(frame)無關。此外,載入管道
的不同階段不必要的緊密耦合在一起,而且在存在底層對象直接存取高層對象的違反層次原則的地方(layering violations)
。例如,MainResourceLoader直接將網路接收到的位元組資料發送給FrameLoader而不通過DocumentLoader。
如果您仔細研究上面的圖,您會發現Cache只用於SubresourceLoader,具體而言,就是主資源載入並沒有得益於WebKit的記憶體
緩衝。如果我們能夠一致的處理兩條載入管道,也許可以提高主資源的載入效能。隨著時間的推移,我們希望提高載入器(loader)的效能,儘快的載入
web頁面。