天天看點

memoryCache和diskCache流程詳解

Webkit的MemoryCache和DiskCache流程詳解

MemoryCache簡介:

    MemoryCache顧名思義,就是将資源緩存到記憶體中,等待下次通路時不需要重新下載下傳資源,而直接從記憶體中擷取。Webkit早已支援memoryCache。

    目前Webkit資源分成兩類,一類是主資源,比如HTML頁面,或者下載下傳項,一類是派生資源,比如HTML頁面中内嵌的圖檔或者腳本連結,分别對應代碼中兩個類:MainResourceLoader和SubresourceLoader。雖然Webkit支援memoryCache,但是也隻是針對派生資源,它對應的類為CachedResource,用于儲存原始資料(比如CSS,JS等),以及解碼過的圖檔資料。

MemoryCache流程分析:(注:以image為例,其他資源流程類似)

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

1.  解析html頁面的時候,解析到img标簽,調用 

HTMLImageElement::create建立HTMLImageElement對象,該對象包含HTMLImageLoader對象m_imageLoader

2. 解析到img的src屬性,調用ImageLoader::updateFromElementIgnoringPreviousError

3. 調用ImageLoader::updateFromElement

4. 調用CachedResourceLoader::requestImage

5. 調用CachedResourceLoader::requestResource,根據緩存的情況policy字段确定是否可以從緩存擷取(use),或者需要revalidate,或者需要直接從網絡擷取(load)

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::didReceiveResponse處理響應頭部,特别是同緩存相關的頭部,比如304的status code。如果是304則直接向緩存擷取,如果是200則通過網絡加載

21.調用ResourceLoader::didReceiveResponse

22.收到體部資料,調用ResourceLoader::didReceiveData

23.調用SubresourceLoader::didReceiveData

24.調用ResourceLoader::didReceiveData

25.調用ResourceLoader::addData将資料存儲到SharedBuffer裡面

26.調用CachedResourceRequest::didReceiveData

27.資料擷取完畢,調用ResourceLoader::didFinishLoading

28.調用SubresourceLoader::didFinishLoading

29.調用CachedResourceRequest::didFinishLoading

30.調用CachedResource::finish

31.調用CachedResourceLoader::loadDone

32.調用CachedImage::data,建立對應的Image對象,解碼

MemoryCache時序圖:

加入memoryCache:

memoryCache和diskCache流程詳解

從memoryCache擷取:

memoryCache和diskCache流程詳解

DiskCache簡介:

diskCache顧名思義,就是将資源緩存到磁盤中,等待下次通路時不需要重新下載下傳資源,而直接從磁盤中擷取,它的直接操作對象為CurlCacheManager。它與memoryCache最大的差別在于,當退出程序時,記憶體中的資料會被清空,而磁盤的資料不會,是以,當下次再進入該程序時,該程序仍可以從diskCache中獲得資料,而memoryCache則不行。

    diskCache與memoryCache相似之處就是也隻能存儲一些派生類資源檔案。它的存儲形式為一個index.dat檔案,記錄存儲資料的url,然後再分别存儲該url的response資訊和content内容。Response資訊最大作用就是用于判斷伺服器上該url的content内容是否被修改。具體詳見:

http://baike.baidu.com/link?url=n5nx7f8fGB_-B3OieAvMvJIGeBNvipb9qGQhYO0YwwBLg6oxqv_05Up3JUJk4jZyAd-KiCM1Hmg4nR23B5BhSq

DiskCache流程分析:

1.  webkit已啟動,就會建立CurlCacheManager對象

2.  CurlCacheManager構造函數會調用CurlCacheManager::setCacheDirectory

3.  調用fileExists判斷檔案夾是否存在,如果存在繼續,否則調用makeAllDirectories建立檔案夾

4.  調用CurlCacheManager::loadIndex(),如果本地有緩存檔案,它就會從磁盤讀取出來,并将資料儲存在m_index這個變量中,該變量類型為HashMap<String,std::unique_ptr<CurlCacheEntry>> ,分别對應url和資料内容。

5.  調用headerCallback函數,傳回codestatus為304未修改,就會去調用CurlCacheManager::getCachedResponse(),如果是200,就會下載下傳資料,并将資料的url儲存在一個m_LRUEntryList中

6.  調用CurlCacheManager::readCachedData()

7.  調用CurlCacheEntry::readCachedData()

8.  調用CurlCacheEntry::loadFileToBuffer()将檔案中的内容讀取出來儲存在一個buffer中

9.  調用ResourceLoader::didReceiveData()将資料擷取,此時資料沒有通過網絡下載下傳,直接從本地擷取

10.Webkit退出時,調用CurlCacheManager::~CurlCacheManager()

11.調用CurlCacheManager::saveIndex(),該函數會去将m_LRUEntryList中的url擷取并寫入index.dat檔案中

MemoryCache時序圖:

memoryCache和diskCache流程詳解

繼續閱讀