HTML 支持的資源主要包括:HTML、JavaScript、CSS、圖片、SVG、CSS Shader、視頻、音頻、字幕、字體、XSL樣式表等算法
這些資源在 WebKit 中都有不一樣的類表示,公共基類是 CachedResource
。其中 HTML文本的類型爲 MainResource
,對應的資源類型叫 CachedRawResource
類。瀏覽器
基本思想是創建一個緩存池,優先從緩存池中讀取數據。這裏的所說的緩存池是內存緩存。WebKit 從資源池中查找資源的關鍵詞是URL,只要URL不一樣,就被認爲是兩個不一樣的資源緩存
分爲三種:安全
ImageLoader
屬於 HTMLImageElement
CachedResourceLoader
全部特定加載器都共享它來查找並插入緩存資源,屬於 HTML 文檔的對象ResourceLoader
類,WebKit 須要從網絡或者文件中獲取資源的時候使用,只負責獲取資源數據例子:有一個 「img」 元素,「src」是一個有效 URL 地址,當 HTML 解釋器解析到該元素的該屬性,WebKit 會建立一個 ImageLoader
對象來加載該資源,ImageLoader
建立一個緩存資源請求CachedResourceRequest
,並調用CachedResourceLoader
查找緩存資源,若是命中緩存則返回給調用者,若是沒有命中則建立一個資源請求ResourceRequest
,而且調用通用資源加載器加載資源,具體到下面的 ResourceHandleInternal
,依賴於每一個 WebKit 移植的實現策略。服務器
存在默寫資源會阻塞主線程渲染過程,當前的主線程渲染被阻塞時,WebKit 會啓動另一個線程去遍歷後面的 HTML 網頁,收集須要的資源 URL,並能夠併發下載這些資源。網絡
資源池使用 LRU(Least Recently Used 最近最少使用)算法,而且在這個基礎上添加了協商緩存。若是命中緩存,那麼發送一個 HTTP 請求給服務器,說明資源在本地的一些信息,如資源更新時間,服務器根據信息判斷,若是沒有更新,則返回狀態碼 304,那麼直接使用原資源;不然下載最新資源。多線程
Renderer 進程在網頁的加載過程當中須要獲取資源,但因爲安全性(沙箱模型打開的時候,Renderer進程是沒有權限獲取資源的)和效率上(資源能夠共享),Renderer 進程的資源獲取其實是經過進程間通訊將任務交給 Browser 進程來完成。架構
WebKit 的資源加載的優化實際上是交由各個移植來實現的,WebCore 沒有什麼也別的基礎設施,每一個移植的網絡實現是很是不同的。併發
除了 HTTP 協議、DNS 解析等,還包含了 Chromium 爲了減小網絡時間而引入的新技術,例如 SPDY,QUIC異步
URLRequest
類被調用時,會根據 URL 的 「scheme」(協議類型,如:「http://」,「file://」等) 來決定要建立什麼類型的請求,Chromium 使用工廠模式處理不一樣類型的請求,例如 「http://」 類型則會使用 URLRequestJobManager
建立一個 URLRequestJob
類,具體使用哪一個工廠則是一個責任鏈模式,優先判斷是不是用戶自定義的 「scheme」 。URLRequestJob
被建立後,先從 Cookie 管理器中獲取與該 URL 相關的信息,以後使用 HttpTransactionFactory
對象建立 HttpTransaction
對象開啓一個 Http 鏈接的事務。若是請求對應的回覆已經在磁盤緩存中,那麼 Chromium 無需再創建 HttpTransaction
HttpNetworkTransaction
使用 HttpNetworkSession
類來管理會話。經過 HttpStreamFactory
對象來創建 TCP Socket 鏈接。以後 HttpStreamFactory
建立 HttpStream
對象,來處理對象和網絡之間數據的讀寫。SteamSocket
類,它是一個抽象類,再 POSIX 系統和 Windows 系統上有不一樣實現。Chromium 使用 HostResolverImpl
類來解析域名,具體調用的是 「getaddrinfo()」,是一個阻塞式函數,因此使用單獨的線程處理。爲了考慮效率,使用 HostCache
類來保存解析後的域名,還有 DNS 預解析機制。
要求:
實現上主要有兩個類,Backend
(整個磁盤緩存) 和 Entry
(表中的表項)。至少須要一個索引文件和四個數據文件。索引文件用來索引,數據文件又稱塊文件。
索引文件: 包括一個索引頭部和索引地址;頭部用來表示該索引文件的信息(索引文件版本號、索引項數量、文件大小等信息);索引地址表保存各個表項對應的索引地址,直接將文件映射到內存地址。從內存地址能夠找到數據文件,數據文件也是一個文件頭加上後面的塊文件,每一個塊的大小是固定的,當超過 512 字節的時候會爲其分配多個塊。但最多不超過四個,超過一般會用單獨的文件存儲。若是一個表項要分配四個塊,那麼是和塊索引位置是對齊的(起始塊的位置是4的倍數)
表項結構 分爲兩個部分,第一部分標記本身,包括元數據信息和自身內容。另外一部分常常發生變更,主要爲表項的回收算法服務,保存了回收算法所需的信息(LRU回收算法)。
一次 DNS 查詢約 60~120ms,而 TCP 的三次握手也大約幾十毫秒
DNS 預取:利用現有的 DNS 機制,提早解析網頁中可能的鏈接。不是使用前面提到的 Chromium 網絡棧,而是直接利用系統的域名解析機制,不會阻礙當前網絡棧的工做,針對多個域名採起並行處理的方式,每一個域名的解析由一個新線程處理,結束後退出。網頁開發者能夠顯示指定哪些域名來讓 Chromium 解析,使用方法:<link rel="dns-prefetch" href='"htttp://...">
。 用戶地址欄也同理。
TCP 預連接:使用追蹤技術獲取用戶從什麼網頁跳轉到另外一個網頁,利用這些數據、和一些啓發規則來 DNS 預取和 TCP 預連接,這對用戶隱私是一個巨大挑戰。
HTTP1.1 開始增長了管線化技術,能夠將多個 HTTP 請求一次性提交給服務器,無需等待服務器回覆,由於它可能將多個HTTP 請求填充在一個 TCP 數據包內。能在高延遲的連接環境下有明顯的性能提高。
侷限性:須要經過永久鏈接完成,而且只有 GET 和 HEAD 等請求能夠進行管線化。
爲了解決網絡延遲和安全問題,根據 Google 官方數據,能夠將網絡加載時間減小 64%,HTTP2.0 將引入 SPDY 協議,將其做爲基礎來編寫。
SPDY 協議是一種新的會話層協議,是一種棧式結構,被定義在 HTTP 協議和 TCP 協議之間,核心是多路複用,僅使用一個鏈接來傳輸一個網頁中的衆多資源。本質上並無改變 HTTP 協議,只是將 HTTP 協議頭經過 SPDY 來封裝傳輸,數據傳輸方式也沒有發生變化。因此比較容易部署,服務器只須要插入 SPDY 協議的解釋層,從 SPDY 的消息頭中獲取各個資源的 HTTP 頭便可。但 SPDY 必須創建在 SSL 層之上。
特徵:
QUIC 是一種新的網絡傳輸協議,目標是改進 UDP 數據協議的能力,解決傳輸層的傳輸效率,並提供數據的加密,SPDY 能夠在 QUIC 上工做。