一篇文章理解Web快取

發表於2018-08-09

最近把前端快取重新整理了一下,從整體的層面上把前端所有能用的快取方案梳理了一遍。同時,對於http快取,使用了表格的方案,使得原先晦澀難記的特性變得清晰明瞭。特記錄於此,若有什麼欠缺,也望不吝指出。

1. 前端快取概述

前端快取主要是分為HTTP快取和瀏覽器快取。其中HTTP快取是在HTTP請求傳輸時用到的快取,主要在伺服器程式碼上設定;而瀏覽器快取則主要由前端開發在前端js上進行設定。下面會分別具體描述。

clipboard.png

2. 前端快取分類

2.1 HTTP快取

整體流程:HTTP快取都是從第二次請求開始的。
第一次請求資源時,伺服器返回資源,並在respone header頭中回傳資源的快取引數;第二次請求時,瀏覽器判斷這些請求引數,擊中強快取就直接200,否則就把請求引數加到request header頭中傳給伺服器,看是否擊中協商快取,擊中則返回304,否則伺服器會返回新的資源。

HTTP快取分為強快取和協議快取,它們的區別如下:

clipboard.png

200 from disk or 200 from memory :
強快取的200也有兩種情況:200 from disk和200 from memory。現在我沒有找到明確的文件來描述這種區別的發生條件。知乎這個問題中提到了一些情景,可以自行取用。

2.1.1 強快取

clipboard.png

2.1.2 協商快取

協商快取都是成對出現的。
clipboard.png

2.1.3 最佳優化策略-消滅304

最佳優化策略:因為協商快取本身也有http請求的損耗,所以最佳優化策略是要儘可能的將靜態檔案儲存為較長的時間,多利用強快取而不是協商快取,即消滅304。

但是給檔案設定一個很長的Cacha-Control也會帶來其他的問題,最主要的問題是靜態內容更新時,使用者不能及時獲得更新的內容。這時候就要使用hash的方法對檔案進行命名,通過每次更新不同的靜態檔名來消除強快取的影響。

Hash命名:
http://xxx.com/main.5eas34fa.js
http://xxx.com/main.js?5eas34fa
http://xxx.com/5eas34fa/main.js

2.2 瀏覽器快取

2.2.1 本地儲存小容量

Cookie主要用於使用者資訊的儲存,Cookie的內容可以自動在請求的時候被傳遞給伺服器。
LocalStorage的資料將一直儲存在瀏覽器內,直到使用者清除瀏覽器快取資料為止。
SessionStorage的其他屬性同LocalStorage,只不過它的生命週期同標籤頁的生命週期,當標籤頁被關閉時,SessionStorage也會被清除。

clipboard.png

2.2.2 本地儲存大容量

WebSql和IndexDB主要用在前端有大容量儲存需求的頁面上,例如,線上編輯瀏覽器或者網頁郵箱。

clipboard.png

2.2.3 應用快取與PWA

應用快取全稱為Offline Web Application,它的快取內容被存在瀏覽器的Application Cache中。它也是一個被W3C標準廢棄的功能,主要是通過manifest檔案來標註要被快取的靜態檔案清單。但是在快取靜態檔案的同時,也會預設快取html檔案。這導致頁面的更新只能通過manifest檔案中的版本號來決定。而且,即使我們更新了version,使用者的第一次訪問還是會訪問到老的頁面,只有下一次再訪問才能訪問到新的頁面。所以,應用快取只適合那種常年不變化的靜態網站。如此的不方便,也是被廢棄的重要原因。

PWA全稱是漸進式網路應用,主要目標是實現web網站的APP式功能和展示。儘管PWA也有manifest檔案,但是與應用快取卻完全不同。不同於manifest簡單的將檔案通過是否快取進行分類,PWA用manifest構建了自己的APP骨架。另外,PWA用Service Worker來控制快取的使用。這一塊的內容較多,在這裡就不詳細展開了。

clipboard.png

2.2.4 往返快取

往返快取又稱為BFCache,是瀏覽器在前進後退按鈕上為了提升歷史頁面的渲染速度的一種策略。BFCache會快取所有的DOM結構,但是問題在於,一些頁面開始時進行的上報或者請求可能會被影響。這個問題現在主要會出現在微信h5的開發中

去除BFCache有多種方法,但不是本文的重點,想了解的同學可以看《瀏覽器往返快取(Back/Forward cache)問題的分析與解決

總結

本文梳理了前端所有可能涉及的快取,希望能從整體層面建立起系統的快取知識體系。限於篇幅,每一部分的描述都比較簡略,僅起到拋磚引玉之用。如有錯誤,還望指出。

相關文章