Service worker (@nuxtjs/workbox) 采坑记

PWA(Progressive Web App)是前端的大趋势,它能极大的加快前端页面的加载速度,获得近乎原生 app 的展现效果(其实难说)。PWA 实际上是多种前端技术的组合,其中最重要的一个技术就是 service worker。html

Service worker 在 MDN 上的说明:前端

Service workers 本质上充当Web应用程序与浏览器之间的代理服务器,也能够在网络可用时做为浏览器和网络间的代理。它们旨在(除其余以外)使得可以建立有效的离线体验,拦截网络请求并基于网络是否可用以及更新的资源是否驻留在服务器上来采起适当的动做。他们还容许访问推送通知和后台同步API。

其实不用太纠结,简单起见咱们就把它当成更高级更先进的 AppCache 就行了。node

在 nuxt(Vue) 网站中启用 Service worker

借近期公司官网升级之机,我也给公司官网上了 Service worker 作离线缓存。git

大前提:Service worker 只可在 https(或 localhost)下使用,首先确保你的网站上了 httpsgithub

在 nuxt 程序中启用 Service worker 很是方便。nuxt 提供了官方 module——pwa-module 用于支持 PWA 网站,其中就包含了用于实现 Service worker 的 workbox moduleworkbox 其实是指的 google 为简化 Service worker 开发而开源的第三方库。web

首先安装依赖shell

$ yarn add @nuxtjs/pwa @nuxtjs/workbox

而后再配置文件中启用浏览器

// modules
module.exports = {
  [ '@nuxtjs/pwa' ]
}

就完成了缓存

SW 使用采坑

官网上线后发现,启用 Service worker 后 Safari 不能播放视频了。可是直接输入视频连接却能够播放。通过各类 google 搜索查资料后找到了官方 issue:服务器

  1. https://github.com/nuxt-commu...
  2. https://github.com/angular/an...

甚至还找到了有人给 webkit(Safari 浏览器内核)开了bug:https://bugs.webkit.org/show_...

状态始终是 new,没有人解决。但 issue 中详细说明了 Safari 的行为以及产生问题的缘由

问题的缘由在于对于视频文件请求,浏览器会发出带有 Range 头的请求部分获取文件内容。Safari 比较奇葩,对于视频文件请求,它一开始就会发一个 Range: 0-1 的请求,可是 Service worker 中处理请求的逻辑不能识别 Range 请求,把 Range 请求当成普通请求处理,返回了 200。Safari 把 200 当成了失败请求,致使请求视频文件失败。

最后开各人的回帖找到了这里:https://developers.google.com...

而后通过各类尝试(中间过程略),说一下可行方案:

首先添加 js plugin:

// workbox-range-request.js
workbox.routing.registerRoute(
  /.*\.(mp4|webm)/,
  workbox.strategies.cacheFirst({
    plugins: [
      new workbox.rangeRequests.Plugin(),
    ],
  }),
  'GET'
);

这个文件给 workbox 注册一个路由,指定对于视频文件(以 .mp4 或 .webm 结尾的文件。若是你的网站有音频文件也要一并处理)处理程序添加 rangeRequests 插件

而后在配置文件中注册插件:

// modules:
[ '@nuxtjs/pwa', {
  workbox: {
    cachingExtensions: '@/plugins/workbox-range-request.js',
  }
} ],

注意必须使用 cachingExtensions 而不能用 routingExtensions,虽然注册的是路由配置

这样 Service worker 就能够处理带 Range 头的请求了,可是还不算完。workbox 会请求 googlecdn 动态加载 js 脚本,若是你身在兲朝,因为众所周知的缘由加载脚本会失败。

解决方案:

  1. 首先去 workbox 官网下载 release 包(笔者用的是 3.5.0 版本):https://github.com/GoogleChro...
  2. 解压后放在你项目的 static 文件夹下,笔者是 static/workbox-v3.5.0
  3. 修改配置
// modules:
[ '@nuxtjs/pwa', {
  meta: false,
  workbox: {
    config: { modulePathPrefix: '/workbox-v3.5.0' },
    cachingExtensions: '@/plugins/workbox-range-request.js',
  }
} ],

配置中指定 workbox 从 /workbox-v3.5.0 这个路径加载 js 脚本,而不走 googlecdn。

注意配置中使用的 config 当前版本(@nuxtjs/pwa@2.5.0, 2018-09-20)还不支持,笔者给官方仓库开了 Pull request 还在审核中,笔者是直接修改了 node_modules 里的文件。

在上 Service worker 以前最好想清楚。这玩意和 AppCache 同样,上线简单,想要下线就难了

请上公司官网体验效果:https://www.eoitek.com

clipboard.png

相关文章
相关标签/搜索