使用 Service Worker 优化网站

Author Avatar
Wincer 7月 25, 2017
  • 在其它设备中阅读本文章

静态博客的内容是很适合用缓存来加速访问的,除了采用常见的 CDN 加速和压缩博文等方法,通过客户端也可以实现加速访问,本文介绍的是「服务工作线程—— Service Worker」。关于 Service Worker 的具体介绍见这里。本文主要需要的是它的离线加载的特性。

本博客使用 Service Worker 可分为两个阶段,在我最初撰写本文的时候,使用的是 Service Worker 原生的接口。在不久之后,Google 推出了 sw-toolboxsw-precache 用以让用户更全面的掌控 Service Worker 缓存的方式:包括版本控制、文件缓存级别、具体路径等,于是在我经历了漫长的实践后(其实是因为懒),有了本文 Version 2.0。

启用 Service Worker

添加注册代码

以下注册代码需要在网站的根目录添加,这样才能保证接管整个网站的全部资源。

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js')
    .then(function() {
        console.log('A new service worker is being installed.');
    })
    .catch(function(error) {
      console.log('Service worker registration failed:', error);
    });
  } else {
    console.log('Service workers are not supported.');
  }

将以上代码加入主题中,至于加在哪需要根据主题的结构决定。你只需要保证生成的静态资源中包含以上代码,那么就算添加成功。以 NexT 为例,你可以把以上代码添加到 /next/layout/_thrid-party/comments/ ` 下的任一评论配置文件中(前提是你开启了该评论组件)。

添加静态资源

将以下代码保存为 sw.js,并确保生成静态文件的时候,sw.js 在网站根目录下(你可以把它放在 source 文件夹内)。

 "use strict";
 (function() {
     var cacheVersion = "-180503";
     var staticCacheName = "asset" + cacheVersion;
     var maxEntries = 100;
     self.importScripts("https://cdn.jsdelivr.net/npm/[email protected]/sw-toolbox.js");
     self.toolbox.options.debug = false;
     self.toolbox.options.networkTimeoutSeconds = 1;

     /* staticImageCache */
     self.toolbox.router.get("/(.*)",self.toolbox.cacheFirst, {
         cache: {
          name: staticCacheName,
             maxEntries: maxEntries
         }
     })
 })();

首先指定 cacheVersion,在刷新缓存的时候会进行匹配;其次是一个 Cache Storage 名称的有关变量,我这里只是简单划分为静态资源——全部从缓存中加载的资源;关闭 debug 模式,设置 Timeout 时间为 1s。

其中 sw-toolbox 的缓存级别共有 5 个(网络优先、缓存优先、速度优先、仅缓存、仅网络)。

我这里采用的是 cacheFirst,即缓存优先加载。可针对具体的资源进行不同的缓存级别分配。

其中 self.toolbox.router.get 表示每一个你需要操作的资源,第一个参数表示匹配的网址,第二个表示缓存级别,第三个是回调函数。

具体到以本站为例的话,你可以参考本站的配置文件

加速效果

离线

可以看到在启用了 Offline 仍然可以加载页面

效果1

效果1

缓存

刷新页面可以看到许多资源是直接 ( from ServiceWorker ) 加载的,并未发起新的 http 请求。

效果2

效果2

先决条件

浏览器

is Serviceworker ready 详细列出了所有浏览器支持的情况。

HTTPS

服务器工作线程只能工作在 HTTPS 加密的网站上,本地的 localhost 是默认安全。

参考文章: