iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 9
1
Modern Web

你應該要知道的新一代Web技術---漸進式網頁(PWA)系列 第 9

[Day09] 在Service Worker中實作Caching(Part2)

接續昨天的進度,我們已經pre-cache app.js這個檔案了,但是我們監聽fetch event時還時直接回應從網路fetch回來的結果,沒有從cache裡取出暫存的response(如下)。這樣沒有網路時,還是一樣的結果阿QQ

self.addEventListener('fetch', function(event) {
    event.respondWith(fetch(event.request));
});

所以來更改一下event.respondWith()裡面的回傳內容吧:

self.addEventListener('fetch', function(event) {
    event.respondWith(
        caches.match(event.request).then(function(response) {
            if(response) {
                return response;
            } else {
                return fetch(event.request);
            }
        })
    );
});

一開始用caches.match()查詢要傳送的request是否存在sub cache中。若存在(也就是response不為null),就直接回傳cache中暫存的response;但response為null的話,則再透過網路用fetch request獲取該資源。

我們可以開啟developer tools中的Network查看app.js:(可以看到檔案是Service Worker從cache中取得的)

接著我們將index.html加入到cache中看看當網路offine時的結果:(記得在chrome developer tools的Service Worker點擊offline,這會切斷browser對外部網路的連線)

確認static cache有暫存到

咦!! 怎麼offline沒有從cache取回index.html頁面哩

這裡有一個地方需要注意!!! /images/emoticon/emoticon19.gif
事實上是有的,只是我們暫存的是cache.add('/index.html')[根部錄下的index.html頁面],所以url要改成localhost:8080/index.html才有response。為了讓首頁在offline時能正常瀏覽必須要再加上cache.add('/')。

讓我們把app shell中其他的資源加到cache中吧:(為了撰寫的方便性,這裡我改成使用addAll方法)

self.addEventListener('install', function(event) {
    console.log('[Service Worker] Installing Service Worker ...', event);
    event.waitUntil(
        caches.open('static').then(function(cache) {
            console.log('[Service Worker] Precaching App Shell');
            cache.addAll([
                '/',
                '/index.html',
                '/src/js/app.js',
                '/src/js/feed.js',
                '/src/js/promise.js',
                '/src/js/fetch.js',
                '/src/js/material.min.js',
                '/src/css/app.css',
                '/src/css/feed.css',
                '/src/images/main-image.jpg',
                'https://fonts.googleapis.com/css?family=Noto+Sans+TC&display=swap',
                'https://fonts.googleapis.com/icon?family=Material+Icons',
                'https://cdnjs.cloudflare.com/ajax/libs/material-design-lite/1.3.0/material.indigo-pink.min.css'
            ]);
        })
    );
});

把html、js、css和外部CDN的response暫存到cache後,看一下offline時畫面結果:

OK就整體畫面來說,不管是頁面、CSS還是圖片該暫存的都暫存到了,只是左上和右下的icon好像沒有出現QQ。為什麼?
針對這些material icons我在上面已經pre-cache https://fonts.googleapis.com/icon?family=Material+Icons 了,但是我們在Network好好的來看一下這段CDN request的回應結果:

結果發現在@font-face的src裡它又再去向另外一個外部url請求資源,我們當初並沒有把這些也暫存到,所以當然離線時icon是不會顯示出來的。/images/emoticon/emoticon04.gif

這裡我先留個伏筆,我會在實作Dynamic Caching時修復這個問題


那...Dynamic Caching是啥??

到目前為止,我們考慮了pre-caching(明確定義要儲存在cache中的資源),但是如果我們想從cache中獲取其他任何外部資源,那它就會失敗。所以我們也可以「動態地將資源添加到cache中」,希望確保像是發出額外HTTP Request的icon或者如果用戶訪問了其他頁面,當再次訪問時,可以直接從cache中獲取。


當載入index.html、app.js文件時,都會發出一些fetch event,因為某些資源是透過外部導入來獲取的。在這種情形下我們可能希望先透過網路獲取該資源,然後使用cache API將獲取的資源暫存在cache中。因此,Dynamic caching意味著動態地向cache添加資源,我們可以在需要時才暫存它們。

Day09 結束!! /images/emoticon/emoticon12.gif


上一篇
[Day08] 在Service Worker中實作Caching(Part1)
下一篇
[Day10] 在Service Worker中實作Caching(Part3)
系列文
你應該要知道的新一代Web技術---漸進式網頁(PWA)29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言