緩存(持續更新)
來自專欄 前端
作為計算機科學最難的問題之一,我們有必要深入了解一下。
緩存的意義
對於一個網站來說,網頁資源是必不可少的,在如今對網頁內容要求越來越高的情況下,一個頁面會包含大量的資源,比如圖片、JS、CSS,這是最常見的也是最不可或缺的資源。然而它們往往文件體積比較大、帶寬佔用大、下載耗費時間長。每次訪問相同的頁面,都做一次無謂的下載,無疑是一種浪費,根本沒必要更新的東西為什麼還要等待下載。一個載入快的頁面和一個慢吞吞才顯示的頁面給用戶帶來的是完全不同的感覺。
緩存控制
Cache-Control是HTTP/1.1中的通用欄位,也就是說可用於請求和響應,通過這個欄位可以做緩存控制。關於它的一些指令:
public:只能用於響應。表明該響應可以被任何中間人緩存,一般用於不攜帶個人信息的資源,這樣CDN就可以緩存,可以縮短網路傳輸距離。
private:只能用於響應。表明中間人不能緩存該響應,只能用於個人,比如存儲在個人瀏覽器中,一般用於攜帶有個人信息的資源,比如針對某個session渲染好的html。
no-cache:為了防止從緩存中返回過期的資源。如果請求中攜有該指令,表明強制向伺服器驗證資源是否過期。
no-store:表明不能緩存。
max-age:表明緩存的相對時間(秒)。如果響應包含該指令,則瀏覽器在文件失效前不會再發起資源有效性確認。如果同時存在Expires欄位,則會忽略Expires,而在HTTP/1.0中,max-age會被忽略。
另外,Pragma含義與Cache-Control: no-cache相同,屬於HTTP/1.0欄位。同時寫上Pragma和Cache-Control是必要的,一條鏈路的中間伺服器HTTP協議版本可能不同。
新鮮度
資源被緩存後,就會有一個過期時間。如果請求該資源時,瀏覽器檢測到資源已經失效,便會在請求頭中附加一個If-None-Match欄位發送給伺服器。下面我們來驗證一下:
為了防止web框架在響應的時候自己增加etag/lastModified,便於請求頭的控制,我們使用了如下方式:
router.get(/image, (req, res) => { res.header(Cache-Control, max-age=10) fs.createReadStream(path.join(__dirname, ../public/test.jpg)).pipe(res)})
設置了Cache-Control並返回了一張圖片,得到了比較乾淨的響應頭:
在10秒內,我們刷新頁面。
靜靜地等待10秒後,我們刷新。
觀察http報文,發現跟上面的一樣,並沒有所謂附加的If-None-Match,這樣一來,我們有理由懷疑MDN文檔中描述的準確性,因為響應時關閉了ETag,等資源過期後,當然沒有對應的If-None-Match了。所以想要附加這個欄位,必須要在設置緩存的同時返回ETag。
緩存驗證
chrome://view-http-cache
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching_FAQ
推薦閱讀:
※OSI-TCP/IP協議族
※Weex Ui 半年開源之路
※奇舞周刊第 257 期:我從小程序學到了什麼
※[閱 #40] 幾點關於更好書寫 CSS 選擇器的建議
※狼叔:Node.js 源碼是如何執行的?| Live 預告
TAG:前端開發 |