一些準備css
在開始這個話題以前,咱們有必要簡單回顧一下 瀏覽器(webkit)的網頁渲染過程(若是想要詳細瞭解這個過程,能夠戳我幾年前寫的一篇文章。):html
咱們知道,瀏覽器在渲染過程當中,如遇到節點須要依賴其餘資源(好比:圖片、CSS、JavaScript、video等),瀏覽器會經過網絡去加載它們。這其中大部分的資源是異步加載的,不會阻塞渲染,除了 JavaScript(未被標記爲異步的方式)。web
網頁的加載和渲染依賴網絡與資源加載,網頁自己是一種資源,它所依賴的 js、css、圖片、視頻等也是資源。而資源的加載涉及網絡和資源的緩存等機制,並且它們充斥着整個渲染過程。算法
1、資源chrome
HTML 中支持的資源主要包括如下類型:瀏覽器
在 webkit 內部,會使用不一樣的類去表示它們,其對應關係:緩存
資源類型 | 內部表示類 |
HTML | CachedRawResource |
JavaScript | CachedScript |
CSS 樣式表 | CachedCSSStyleSheet |
CSS Shader | CachedShader |
圖片 | CachedImage |
SVG | CachedSVGDocument |
字幕 | CachedTextTrack |
字體文件 | CachedFont |
XSL 樣式表 | CachedXSLStyleSheet |
以上內部表示類均繼承自 CachedResource 類。 聰明的你必定發現了, 這些類名都是以 「Cached」 開頭,這實際上是考慮到效率問題二引入的緩存機制。全部對資源的請求都會先獲取緩存中的信息,以決定是否向服務器發起資源請求。服務器
2、資源緩存 網絡
資源的緩存機制是提升資源使用效率的有效方法。在 webkit 內部,它的基本思想是創建一個資源的緩存池(內存緩存),當須要請求資源時,會先從資源池中查找是否存在響應的資源。若是存在,則直接使用緩存池中的資源。若是不存在,則發送真正的請求加載資源,收到響應的資源後,webkit 會將其設置到上面提的到資源類中去。異步
這些資源,在 webkit 內部是以 URL 做爲 key 去查找的。由於 URL 是標記資源的惟一性的特徵。
3、資源加載器
webkit 總共有 3 種資源加載器:
以 ImageLoader 這個特定資源加載器爲例,大體可用下圖描述:
結合 chrome 瀏覽器調試工具,以訪問百度首頁爲例,來觀察百度 logo 的請求狀況。爲防止以前的緩存,採用 「清除緩存並硬性從新加載」 方式訪問。表現以下:
再正常不過的 200, 沒有 from * cache 標識意味着來源於網絡。新開 tab, 再次訪問百度首頁:
發如今 size 列(倒數第二列)多了 「(from disk cache)」 字樣。在此基礎上(不關閉 tab),正常刷新該頁面:
聰明的你必定發現 了原來 size 列的 「from disk cache」 變爲了 「from memory cache」。顧名思義,兩張圖片的加載方式由從 磁盤緩存讀取 變爲了 從內存緩存讀取。摘一段官網上的文檔(文檔地址):
簡單翻譯:Chrome 使用兩種緩存:磁盤緩存和高速的內存緩存。內存緩存(memory cache)依附於渲染進程,咱們能夠大體認爲一個渲染進程就等於一個 tab。
所以,「from memory cache」 只有在正常刷新的狀況下,纔會命中。這也解釋了前面示例中新打開的 tab 訪問百度首頁,獲得的是 「from disk cache」。
4、過程
通過前面的介紹,咱們創建起了對 資源、資源緩存、資源加載器 的認知。接下來詳細聊聊資源的加載過程。仍是以圖片加載爲例:
咱們都知道,在網頁加載時,如遇到 script 標籤(未聲明異步),會阻塞渲染。在這種狀況下,webkit 會啓動另一個去遍歷後面的 HTML 網頁,收集須要的資源的 URL,而後發送請求,以此來避免阻塞。
回到資源緩存的話題,前面提到,在 webkit 內部是存在一個 「緩存池」 。爲了保證在有限空間的緩存池內可以持續的插入新的緩存,它使用 LRU 算法來管理緩存。