HTTP緩存 && Service Worker

溫馨提示
本文只是下面兩篇文章
HTTP緩存
Caching best practices & max-age gotchas
的閱讀理解佳遂。如有錯誤請不吝賜教蒋情!

前段時間看了Service Worker沙廉,今天看了HTTP緩存,既然都是緩存厂置,那么它們之間必定就有聯(lián)系厚宰。
HTTP緩存的內(nèi)容不多,總結(jié)成了一張思維導(dǎo)圖鲫竞,具體可以看這篇文章:
HTTP緩存

HTTP緩存

還有文章里一張很干貨的圖辐怕,什么時候用什么緩存策略:
HTTP緩存策略

關(guān)于緩存策略還可以參考這篇文章:
Caching best practices & max-age gotchas
文章主要思想如下:

  1. 不變的內(nèi)容,用大的max-age从绘,比如Cache-Control: max-age=31536000寄疏,當(dāng)文件發(fā)生修改,可以通過同步更新文件名(比如僵井,style-v1.css , style-v2.css)的方式在強(qiáng)制更新緩存陕截。
    這種方法不適用于博客類的網(wǎng)頁,因為博文的url無法版本化批什。
  2. 經(jīng)常改變的內(nèi)容农曲,每次請求都要向服務(wù)器驗證其內(nèi)容沒變,Cache-Control: no-cache
  3. 適當(dāng)使用max-age會有效減輕服務(wù)器壓力渊季,但有時把max-age用在經(jīng)常改變的內(nèi)容上可能會有很嚴(yán)重的后果朋蔫。
    舉個例子,現(xiàn)在HTTP緩存了index.html, style.css, script.js却汉,在新鮮期內(nèi)驯妄,緩存器丟失了style.css,而服務(wù)器剛好又更新了這三個文件合砂。
    現(xiàn)在我請求這三個文件青扔,緩存器會返回緩存的index.html, script.js,因為style.css丟了,所以他要向服務(wù)器請求新的css文件微猖。
    那么谈息,現(xiàn)在,我得到了舊的html凛剥,js文件侠仇,新的css文件,會出現(xiàn)什么情況呢犁珠?
    整張頁面的樣式可能全亂掉了逻炊。
    更可怕的是,因為三者的max-age是一樣的犁享,那么緩存器請求了新的css文件余素,css文件的到期時間和html,js文件就變得不同步了炊昆!這樣的連鎖反應(yīng)導(dǎo)致的后果就是桨吊,以后緩存器中的style.cssindex.html, script.js可能會一直保持早不兼容的狀態(tài)。
  4. 如何解決這個問題呢凤巨?一種方法是用戶刷新頁面视乐,因為刷新頁面會繞過max-age,向服務(wù)器重新驗證內(nèi)容是否為最新磅甩。但是這么做會降低用戶對網(wǎng)站的好感度炊林。
  5. 第二種方法是和Service Worker合作。

終于進(jìn)入正題了~~卷要!
我們可能會想要用SW來代替HTTP緩存,比如現(xiàn)在寫一個這樣的sw.js

const version = '2';

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(`static-${version}`)
      .then(cache => cache.addAll([
        '/styles.css',
        '/script.js'
      ]))
  );
});

self.addEventListener('activate', event => {
  // …delete old caches…
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});

這段代碼說独榴,每次更新SW僧叉,SW在install階段中,會緩存/styles.css, /script.js兩個文件棺榔,之后會捕獲用戶的網(wǎng)絡(luò)請求瓶堕,先去找緩存里有沒有對象的響應(yīng),沒有的話再走正常的網(wǎng)絡(luò)流程症歇。

但是很尷尬的是郎笆,也許你已經(jīng)從前面的“正常的網(wǎng)絡(luò)流程”的字里行間看出來了,如果SW發(fā)送了一個網(wǎng)絡(luò)請求忘晤,請求也會經(jīng)過緩存服務(wù)器宛蚓,緩存服務(wù)器很可能會返回緩存的文件。也就是說设塔,我們還是會得到不兼容的版本凄吏。

同樣的道理,SW在install階段緩存的這兩個文件,也很有可能是不兼容的舊版本痕钢。

那我們要怎么避免這種情況图柏?一個辦法是讓SW每次發(fā)送的url都不一樣,這樣就繞過了HTTP緩存了任连。

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(`static-${version}`)
      .then(cache => Promise.all(
        [
          '/styles.css',
          '/script.js'
        ].map(url => {
          // url中添加一個隨機(jī)數(shù)
          return fetch(`${url}?${Math.random()}`).then(response => {
            // fail on 404, 500 etc
            if (!response.ok) throw Error('Not ok');
            return cache.put(url, response);
          })
        })
      ))
  );
});

有一些瀏覽器已經(jīng)支持了Request接口的cache選項蚤吹,可以直接這么寫:

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(`static-${version}`)
      .then(cache => cache.addAll([
        new Request('/styles.css', { cache: 'no-cache' }),
        new Request('/script.js', { cache: 'no-cache' })
      ]))
  );
});

我們似乎已經(jīng)解決了問題,但是随抠,用SW代替HTTP緩存可行嗎距辆?‘
看一下SW的兼容性,是不是淚流滿面暮刃?因為這種方案只能解決支持SW的瀏覽器的問題跨算。

更好的方法是兩者結(jié)合。

在HTTP緩存中椭懊,把根頁面的緩存機(jī)制設(shè)為:no-cache诸蚕,css,js文件用版本號控制變更氧猬,然后使用max-age=...的緩存策略背犯。每次我們更新css或者js文件,文件名也會改變盅抚。

使用下面的sw.js代碼:

const version = '23';

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(`static-${version}`)
      .then(cache => cache.addAll([
        '/',
        '/script-f93bca2c.js',
        '/styles-a837cb1e.css',
        '/cats-0e9a2ef4.jpg'
      ]))
  );
});

每次SW更新時漠魏,都會觸發(fā)一次對根頁面的請求。而css妄均,js文件只有在文件名改變時柱锹,才會打擾遠(yuǎn)程服務(wù)器。

如此丰包,我們避免了版本不兼容的問題禁熏,也有效的節(jié)省了帶寬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末邑彪,一起剝皮案震驚了整個濱河市瞧毙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寄症,老刑警劉巖宙彪,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異有巧,居然都是意外死亡释漆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門剪决,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灵汪,“玉大人檀训,你說我怎么就攤上這事∠硌裕” “怎么了峻凫?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長览露。 經(jīng)常有香客問我荧琼,道長,這世上最難降的妖魔是什么差牛? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任命锄,我火速辦了婚禮,結(jié)果婚禮上偏化,老公的妹妹穿的比我還像新娘脐恩。我一直安慰自己,他們只是感情好侦讨,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布驶冒。 她就那樣靜靜地躺著,像睡著了一般韵卤。 火紅的嫁衣襯著肌膚如雪骗污。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天沈条,我揣著相機(jī)與錄音需忿,去河邊找鬼。 笑死蜡歹,一個胖子當(dāng)著我的面吹牛屋厘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播季稳,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼擅这,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了景鼠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤痹扇,失蹤者是張志新(化名)和其女友劉穎铛漓,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲫构,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡浓恶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了结笨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片包晰。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡湿镀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伐憾,到底是詐尸還是另有隱情勉痴,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布树肃,位于F島的核電站蒸矛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胸嘴。R本人自食惡果不足惜雏掠,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劣像。 院中可真熱鬧乡话,春花似錦、人聲如沸耳奕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吮铭。三九已至时迫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谓晌,已是汗流浹背掠拳。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留纸肉,地道東北人溺欧。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像柏肪,于是被迫代替她去往敵國和親姐刁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容