扼杀 304,Cache-Control: immutable
隨著近些年社交網(wǎng)站的流行,越來(lái)越多的人學(xué)會(huì)了“刷”網(wǎng)頁(yè) ──?刷微博,刷朋友圈,刷新聞,刷秒殺頁(yè)。這里的“刷”,就是刷新的意思,在瀏覽器里,你可以通過(guò)點(diǎn)擊刷新按鈕,或者用快捷鍵,或者移動(dòng)端的下拉操作來(lái)進(jìn)行刷新。
但普通網(wǎng)民不知道的是,通過(guò)刷新操作導(dǎo)致的頁(yè)面加載和通過(guò)其他操作(比如點(diǎn)擊頁(yè)面鏈接,地址欄輸入網(wǎng)址并回車(chē),點(diǎn)擊收藏夾網(wǎng)址等)導(dǎo)致的頁(yè)面加載有一點(diǎn)不同,那就是刷新操作會(huì)給該頁(yè)面的請(qǐng)求本身以及頁(yè)面里所引用的資源們(JS,CSS,圖片等)的請(qǐng)求加上?If-Modified-Since 和?If-None-Match 請(qǐng)求頭(如果已經(jīng)有緩存且有 Last-Modified/ETag?響應(yīng)頭的話),服務(wù)器會(huì)根據(jù)這兩個(gè)請(qǐng)求頭判斷該資源有沒(méi)有更新過(guò),如果沒(méi)有,就返回不帶響應(yīng)體的 304 響應(yīng),告訴瀏覽器:“用緩存吧”,如果更新過(guò)了,則把更新后的資源放在響應(yīng)體里返回 200 響應(yīng)。
我們把上面說(shuō)的這種帶有 If-Modified-Since 或 If-None-Match 請(qǐng)求頭的?HTTP 請(qǐng)求叫做條件請(qǐng)求,除了刷新操作,條件請(qǐng)求還會(huì)發(fā)生在緩存過(guò)期的時(shí)候,也就是已緩存時(shí)長(zhǎng)大于 Cache-Control 響應(yīng)頭中的 max-age 字段指定的秒數(shù)的時(shí)候。
條件請(qǐng)求是設(shè)計(jì)用來(lái)更新資源的,但實(shí)際情況是,在現(xiàn)如今的網(wǎng)站開(kāi)發(fā)中,尤其是大型網(wǎng)站,會(huì)依賴(lài)適當(dāng)?shù)倪^(guò)期時(shí)長(zhǎng)或者讓用戶(hù)手動(dòng)刷新來(lái)更新頁(yè)面嗎?比如把緩存時(shí)長(zhǎng)設(shè)置成一小時(shí),新版頁(yè)面上線了,用戶(hù)都看不到效果,老板過(guò)來(lái)問(wèn):“這怎么回事啊,不是上線了嗎”,開(kāi)發(fā)回答:“要等一小時(shí)緩存過(guò)期啊,你也可以刷新一下就看到效果了~”。顯然不可能這樣,對(duì)于那些有更新需求的靜態(tài)資源,常見(jiàn)的是 JS、CSS,我們都會(huì)在它的 URL 里加上點(diǎn)東西,時(shí)間戳、版本號(hào)、哈希值等,可以放在 URL 的路徑里,也可以放在查詢(xún)參數(shù)里,因?yàn)橹灰?URL 變了,瀏覽器就認(rèn)為是不同的資源,就會(huì)重新下載;還有一些靜態(tài)資源是完全沒(méi)有更新需求的,比如你在微博上傳的那些圖片,同一個(gè) URL 對(duì)應(yīng)的資源是永遠(yuǎn)不會(huì)變的。
上面說(shuō)的這兩種情況,其實(shí)是一種,就是它們永遠(yuǎn)沒(méi)有更新的需求,它們是不可變的,是?immutable 的,304 用在它們身上完全沒(méi)有意義,全是浪費(fèi)。雖然每個(gè) 304 請(qǐng)求的往返體積只有 1k 左右,但架不住多啊。而且就算只有一個(gè)字節(jié),也會(huì)導(dǎo)致頁(yè)面展現(xiàn)變慢,讀本地文件和讀網(wǎng)絡(luò)資源還是有本質(zhì)區(qū)別的。
Facebook 在一年前意識(shí)到了這個(gè)問(wèn)題,它的工程師給制定 HTTP 標(biāo)準(zhǔn)的?IETF 工作組發(fā)了封郵件,里面說(shuō)到,Facebook 使用版本號(hào)來(lái)更新靜態(tài)資源,還給靜態(tài)資源設(shè)置了幾乎不可能過(guò)期的緩存時(shí)長(zhǎng),但發(fā)現(xiàn)仍然有 20% 的請(qǐng)求是無(wú)意義的條件請(qǐng)求(必然 304),這給服務(wù)器性能帶來(lái)很大傷害,他們研究發(fā)現(xiàn)是因?yàn)?Facebook 頁(yè)面 pv 有 2% 來(lái)自用戶(hù)的刷新操作,他們希望 HTTP 協(xié)議能給 Cache-Control 響應(yīng)頭增加一個(gè)屬性字段表明該資源永不過(guò)期,瀏覽器就沒(méi)必要再為這些資源發(fā)送條件請(qǐng)求了。
今年四月份,Mozilla 的人覺(jué)的 Facebook 提的這個(gè)建議很好,于是他們?cè)?Firefox 49 里實(shí)現(xiàn)了?Cache-Control: immutable。immutable 的推薦用法是和那些超大的 max-age 配合使用,比如 1年:Cache-Control: max-age=31536000, immutable,甚至 10年, 但通常情況下,1 年就夠了,因?yàn)?#xff1a;1. 對(duì)于單個(gè)緩存來(lái)說(shuō),它在某個(gè)瀏覽器里存活的時(shí)長(zhǎng)不可能超過(guò)一年,瀏覽器的緩存空間都有上限,Firefox 256M,Chrome 320M,舊的緩存會(huì)時(shí)不時(shí)被清掉。2. 一個(gè)用戶(hù)不大可能一年后還來(lái)同一個(gè)頁(yè)面,且那個(gè)頁(yè)面還沒(méi)改版。對(duì)緩存時(shí)長(zhǎng)來(lái)說(shuō),1 年就代表永遠(yuǎn)了。
但這只是推薦做法,immutable 并不是真的只能應(yīng)用在那些永不過(guò)期的資源上,也可以配合較小的 max-age 來(lái)使用,比如一些個(gè)人博客,或者一些不太講究及時(shí)更新的站點(diǎn),可以設(shè)置成 Cache-Control: max-age=3600, immutable,表明該資源能存活一小時(shí),在一小時(shí)之內(nèi),即便用戶(hù)刷新也不要發(fā)送條件請(qǐng)求,在過(guò)期之后,瀏覽器會(huì)發(fā)送不帶一個(gè)不帶 If-Modified-Since 和 If-None-Match 的請(qǐng)求來(lái)更新資源,這里需要注意,一旦被標(biāo)志成 immutable,則這個(gè)資源不可能返回 304 響應(yīng)了,只有 200。
目前 Firefox 的實(shí)現(xiàn)里,只對(duì) HTTPS 資源開(kāi)放 immutable 屬性的支持,我通過(guò) Fiddler 在本地篡改了淘寶搜索頁(yè)面?https://s.taobao.com/search?q=連衣裙?里所有資源的 Cache-Control 響應(yīng)頭,在原值尾部加上 “, immutable”。篡改之前,假如我刷新一下此頁(yè)面,會(huì)導(dǎo)致數(shù)十個(gè) 304 響應(yīng):
篡改之后的刷新效果:
注意那些帶有 cached 字樣的 200 請(qǐng)求,那些請(qǐng)求實(shí)際上根本不是真正的請(qǐng)求,只是一次本地讀取文件的操作。
目前 Facebook 還沒(méi)有反饋 immutable 的測(cè)試數(shù)據(jù),畢竟 Firefox 49 還不是正式版,以后應(yīng)該會(huì)有的。不過(guò)考慮到現(xiàn)在 Firefox 的市場(chǎng)占有率,也許 Chrome 實(shí)現(xiàn)之后才會(huì)得到更多人的關(guān)注, Chrome 也表示了有意愿去實(shí)現(xiàn)。不過(guò)我在 GitHub 搜了一下,倒是發(fā)現(xiàn) W3C 的網(wǎng)站和 Firefox 附加組件網(wǎng)站準(zhǔn)備實(shí)現(xiàn)。
immutable 只有在你的網(wǎng)站被頻繁刷新的情況下才有較大的意義。還有雖然它是向后兼容的,但可能一些 CDN 服務(wù)器在識(shí)別 Cache-Control 時(shí)因不認(rèn)識(shí)這個(gè)屬性,導(dǎo)致最終返回給瀏覽器的響應(yīng)丟失了?immutable,推特上有反應(yīng)?Akamai 就這么干了。
少數(shù)人知道的強(qiáng)制刷新功能(Ctrl+F5/Shift+Command+R)以及開(kāi)發(fā)者工具的跳過(guò)緩存功能優(yōu)先級(jí)應(yīng)比 immutable 更高。
轉(zhuǎn)載于:https://www.cnblogs.com/defined/p/6286035.html
總結(jié)
以上是生活随笔為你收集整理的扼杀 304,Cache-Control: immutable的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网易新闻 时事新闻抓取链接
- 下一篇: COM组件简介