日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

WebKit 内核源码分析 (四)

發布時間:2024/4/15 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WebKit 内核源码分析 (四) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文介紹?WebCore??Loader?模塊是如何加載資源的,分主資源和派生資源分析?loader?模塊的類關系。

關鍵詞:?WebKit,Loader,Network,ResouceLoader,SubresourceLoader

一、類結構及接口

Loader?模塊是?Network?模塊的客戶。?Network?模塊提供指定資源的獲取和上傳功能,獲取的資源可能來自網絡、本地文件或者緩存。對不同?HTTP?實現的適配會在?Network?層完成,所以?Loader?接觸到的基本上是同?OS??HTTP?實現無關的Network?層接口。

?


?

如上是?Loader??NetWork?之間的類關系圖,?ResourceHandleClient?ResourceHandle?的客戶,它定義一系列虛函數,這些虛函數是?ResouceHandle?的回調,繼承類實現這些接口。

ResouceHandleClient?的接口同網絡傳輸過程息息相關,一般為某一個網絡事件對應的回調。下面是其中的一些接口。

//?一般情況下,在發起網絡請求前調用,可以設置特定的?Http

頭部,比如?user agent?等,在重定向請求的時候,也會自動調

void willSendRequest(ResourceHandle*, ResourceRequest&, const

ResourceResponse&)

//?上傳數據的時候,在?TCP wrtie?事件的時候,向對方發送數據的

時候調用,?loader?可以根據這個回調顯示上傳進度。

void didSendData(ResourceHandle*, unsigned long long

/*bytesSent*/, unsigned long long /*totalBytesToBeSent*/)

//?收到第一個響應包,此時至少?http?的部分頭部已經解析(如

status code?),?loader?根據響應的頭部信息判斷請求是否成功

等。

void didReceiveResponse(ResourceHandle*,

const???ResourceResponse&)

//?收到?HTTP?響應數據,類似?tcp??read?事件,來?http?響應數據

了,?Network?的設計機制是來一段數據上傳一段數據。

void didReceiveData(ResourceHandle*, const char*, int,

??int /*lengthReceived*/)

????//?加載完成,數據來齊。

void didFinishLoading(ResourceHandle*, double /*finishTime*/)

//?加載失敗

void didFail(ResourceHandle*, const ResourceError&)

//?要求用戶鑒權

void didReceiveAuthenticationChallenge(ResourceHandle*,

const AuthenticationChallenge&)

WebCore?把要加載的資源分成兩類,一類是主資源,比如?HTML?頁面,或者下載項,一類是派生資源,比如?HTML?頁面中內嵌的圖片或者腳本鏈接。這兩類資源對于回調的處理有很大的不同,比如,同樣是下載失敗,主資源可能需要向用戶報錯,派生資源比如頁面中的一張圖下載失敗,可能就是圖不顯示或者顯示代替說明文字而已,不向用戶報錯。因此有了?MainResourceLoader??SubresourceLoader?之分。它們的公共基類?ResourceLoader?則完成一些兩種資源下載都需要完成的操作,比如通過回調將加載進程告知上層應用。

ResourceLoader?通過?ResourceNotifier?類將回調傳導到?FrameLoaderClient?類。


????????

主資源的加載是立刻發起的,而派生資源則可能會為了優化網絡,在隊列中等待(?這里的立刻發起是?loader?層面的,不是?Network?層面的?)??ResourceScheduler?這個類就是用來管理資源加載的調度。主要調度對象就是派生資源,會根據?host?來影響資源加載的先后順序。

主資源和派生資源的加載還有一個區別,主資源目前是沒有緩存的,而派生資源是有緩存機制的。這里的緩存指的是?Resouce Cache?,用于保存原始數據(比如CSS??JS?等),以及解碼過的圖片數據,通過?Resource Cache?可以節省網絡請求和圖片解碼的時候。不同于?Page Cache??Page Cache?存的是?DOM?樹和?Render?樹的數據結構,用來在前進后退的時候快速顯示頁面。

二、加載流程

????下圖是加載?html?頁面時,一個正常的加載流程。

?

三、主資源加載過程

1.????????DocumentLoader?調用?MainResourceLoader::load??loader?發起請求

2.????????調用?MainResourceLoader::loadNow

3.????????調用?MainResourceLoader::willSendRequest

4.????????調用?ResourceLoader::willSendRequest,??callback?通過?ResourceNotifier?傳導給?FrameLoaderClient??Client?可以在回調中操作?ResourceRequest?,比如設置請求頭部。

5.????????調用?PolicyChecker::checkNavigationPolicy?過濾掉重復請求等

6.????????loader?調用?ResourceHandle::create??Network?發起加載請求

7.????????收到第一個?HTTP?響應數據包?,Network?回調MainResourceLoader::didReceiveResponse?,主要處理?HTTP?頭部。

8.????????調用?PolicyChecker::?checkContentPolicy,?并最終通過?FrameLoaderClient?dispatchDecidePolicyForMIMEType?判斷是否為下載請求(存在?"Content-Disposition"http?頭部)

9.????????調用?MainResourceLoader::continueAfterContentPolicy?,根據ResourceResponse?檢測是否發生錯誤。

10.???調用?ResourceLoader::didReceiveResponse?,將?callback?通過?ResourceNotifier傳導給?FrameLoaderClient?

11.???收到?HTTP?體部數據,調用?MainResourceLoader::didReceiveData

12.???調用?ResourceLoader::didReceiveData?,將?callback?通過?ResourceNotifier?傳導給?FrameLoaderClient

13.???調用?MainResourceLoader::addData

14.???調用?DocumentLoader::receivedData

15.???調用?DocumentLoader::commitLoad

16.???調用?FrameLoader::commitProvisionalLoad??FrameLoader??provisional?狀態躍遷到?Committed?狀態

17.???調用?FrameLoaderClientQt::committedLoad

18.???調用?DocumentLoader::commitData?,啟動?Writer?對象來處理數據(DocumentWriter::setEncoding??DocumentWriter::addData?

19.???調用?DocumentWriter::addData

20.???調用?DocumentParser::appendByte

21.???調用?DecodedDataDocumentParser::appendBytes?對文本編碼進行解碼

22.???調用?HTMLDocumentParser::append?,進行?HTML?解析

23.???數據來齊,調用?MainResourceLoader::didFinishLoading

24.???調用?FrameLoader::finishedLoading

25.???調用?DocumentLoader::finishedLoading

26.???調用?FrameLoader::finishedLoadingDocument?,啟動?writer?對象接收剩余數據,重復?19-22?進行解析

27.???調用?DocumentWriter::end?結束接收數據(調用?Document::finishParsing?

28.???調用?HTMLDocumentParser::finish

四、派生資源加載流程

??在派生資源的加載中,?SubresourceLoader?更多起到的是一個轉發的作用,通過它的?client??SubresourceLoaderClient?類)來完成操作。


?

?

???各個加載階段的處理在?SubresourceLoaderClient?的派生類CachedResourceRequest,Loader,IconLoader?中完成。?Client?會創建?SubresourceLoader

請求發起階段,?ResourceLoadScheduler?負責對?SubresourceLoader?進行調度。


???Document?類會創建?CachedResourceLoader?類的對象?m_cachedResourceLoader,這個類?(?對象?)?提供了對?Document?的派生資源的訪問接口?requestImage?requestCSSStyleSheet??requestUserCSSStyleSheet??requestScript??requestFont?requestXSLStyleSheet??requestLinkPrefetch?。為了實現這些接口,CachedResourceLoader?需要創建?CachedResourceRequest?對象來發起請求。

一般情況下,一個?Document?擁有一個?CachedResourceLoader?類實例。

MemoryCache?類則對提供緩存條目的管理,可以方便地進行?add??remove?,緩存淘汰等。具體的緩存條目則是通過?CachedResource?類存儲,?MemoryCache?類維護了一個?HashMap?存儲所有緩存條目。

HashMap <String,CachedResource> m_resources;

CachedResourceRequest?依賴于?CachedResource,??CacheResourceRequest?的構造函數中,會傳入?CachedResource?對象作為參數。?CachedResource?既存儲響應體部,也存儲同?cache?相關的頭部。在發起請求前,會檢查是否有?cache??validator?,在收到響應的時候,則需要更新對應的頭部。?CachedResource?類實現了?RFC2616?中的緩存一節。實際上?CachedResource?類真正完成了同網絡的通信。?CachedResource?類根據申請的資源類型派生出不同的子類。



??????CachedResource?類的使用者必須是?CachedResourceClient,?在這個類中維護了CachedResourceClient?類的集合?m_clients?。每一個?Client?通過?addClient?removeClient?將自己加入到該類的?Client?集合中。?CachedResourceClientWalker?則提供了?CachedResouceClient?的一個遍歷接口。當數據來齊的時候,?CachedResource?類會通過?CachedResouceClient::notifyFinished?接口通知使用者。

下圖是?Image?元素對應的幾個類關系。



?

下面以?image?為例分析其加載過程

1.????????解析?html?頁面的時候,解析到?img?標簽,調用?HTMLImageElement::create創建?HTMLImageElement?對象,該對象包含?HTMLImageLoader?對象m_imageLoader

2.????????解析到?img??href?屬性,調用ImageLoader::updateFromElementIgnoringPreviousError

3.????????調用?ImageLoader::updateFromElement

4.????????調用?CachedResourceLoader::requestImage

5.????????調用?CachedResourceLoader::requestResource(?根據緩存的情況確定是否可以從緩存獲取,或者需要?revalidate?,或者需要直接從網絡獲取?)

6.????????調用?CachedResourceLoader::loadResource

7.????????根據?Resource?的類型調用?createResource?創建對應的?CachedResource

8.????????調用?MemoryCache::add??cache?中查找是否有對應的?cache?條目,如果沒有創建之

9.????????調用?CachedImage::load

10.???調用?CachedResource::load

11.???調用?CachedResourceLoader::load

12.???調用?CachedResourceRequest::load

13.???創建?CachedResourceRequest?對象,它將作為?SubresourceLoader??client

14.???調用?ResourceLoaderScheduler::scheduleSubresourceLoad

15.???調用?SubresourceLoader::create

16.???ResourceLoadScheduler::requestTimerFired

17.???調用?ResourceLoader::start

18.???調用?ResourceHandle::create?發起請求

19.???收到?HTTP?響應頭部,調用?ResourceLoader::didReceiveResponse

20.???調用?SubresourceLoader::didiReceiveResponse

21.???調用?CachedResourceRequest::didReceiveResponse?處理響應頭部,特別是同緩存相關的頭部,比如?304??status code

22.???調用?ResourceLoader::didReceiveResponse

23.???收到體部數據,調用?ResourceLoader::didReceiveData

24.???調用?SubresourceLoader::didReceiveData

25.???調用?ResourceLoader::didReceiveData

26.???調用?ResourceLoader::addData?將數據存儲到?SharedBuffer?里面

27.???調用?CachedResourceRequest::didReceiveData

28.???數據來齊?,?調用?ResourceLoader::didFinishLoading

29.???調用?SubresourceLoader::didFinishLoading

30.???調用?CachedResourceRequest::didFinishLoading

31.???調用?CachedResource::finish

32.???調用?CachedResourceLoader::loadDone

33.???調用?CachedImage::data?,創建對應的?Image?對象,解碼

總結

以上是生活随笔為你收集整理的WebKit 内核源码分析 (四)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。