使用 service worker 和 Workbox 缓存页面

Service worker 是一个在后台运行的脚本,主要用于浏览器和服务器之间的网络交互,从而实现一些新功能。而 Workbox 则是 Google 基于这项功能开发的一个库,使一些常用的功能做到了开箱即用。这两天研究了一番之后用他们给博客加上了缓存功能,于是写个文记录一番。

首先,在页面的脚本里注册 serivce worker。

//scripts.js
if ('serviceWorker' in navigator) {
    window.addEventListener('load', function () {
        navigator.serviceWorker.register('/sw.js');
      });
}

由于 service worker 存在作用域,所以需要放在网站的根目录下。这里我用了 Nginx 的 alias 把 `https://seewang.me/sw.js` 解析回了 WordPress的主题文件夹下方便管理。

    #nginx配置文件
    location = /sw.js {
        alias /path/to/wordpress/wp-content/themes/twentyfifteenone/js/sw.js;
    }

而在 sw.js 中就是 service worker的脚本内容了。首先从 CDN 引用 Wordbox,也可以下载下来从本地加载。

//sw.js
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js')

然后就是缓存逻辑

//sw.js
workbox.routing.registerRoute(
    /\/(en|zh)\/.+/,
    workbox.strategies.staleWhileRevalidate({
        cacheName: 'page-cache',
        plugins: [new workbox.expiration.Plugin({
            maxEntries: 200
        })]
    })
)

workbox.routing.registerRoute函数里第一个参数为匹配资源的正则表达式,这里我匹配了除了主页以外的所有页面。而第二个参数则是缓存策略,这里的staleWhileRevalidate的策略是当需要请求资源时,有缓存则使用缓存,但同时异步请求资源并更新缓存,这样用户下次访问,就能看到最新的页面了。这样既能提高速度,又能保证资源更新。此外也有其他策略来满足不同场景

部署之后测试一下
使用前:
Service worker 使用前

使用后:
Service worker 使用后