Service Workers (PWA 初体验)

在前端愈来愈重的这个时代,页面加载速度成为了一个重要的指标。对于这个问题,业界也有一些解决方案。css

  1. 浏览器缓存、协议缓存、强缓存
  2. 懒加载(首屏)
  3. CDN 多域名突破下载并发限制。

其实在两年前内部就对这块内容作过调研了。appCache方案?PWA方案?可是最后都没选择
以前看代码,发现是 localstroage 存代码,若是有就拿 localstroage 去用。省去了这一部分加载的时间。
上个同事离职了。当时的调研结果我也忘了。只能再开始新一轮的调研,我选择的是 PWA 方案。(若是说是网速拖慢了加载速度,那么个人网页能够离线访问不就速度起飞了?)
网上的资料不多。我但愿我能够写一篇帮助下一个想使用 PWA 方案的人。html

Service Workers

Service worker是一个注册在指定源和路径下的事件驱动worker前端

Service worker运行在worker上下文,所以它不能访问DOM。不一样于主线程,它运行在其余线程中,因此不会形成主线程阻塞。它设计为彻底异步,同步API(如XHR和localStorage)不能在service worker中使用vue

Service workers 本质上充当Web应用程序(服务端)浏览器(客户端)之间的代理服务器
能够提供有效有效的离线体验,拦截网络请求。还能够推送通知。webpack

Service Workers 须要注意的地方

  1. 须要支持 HTTPS 访问你的页面。出于安全缘由,Service Workers 要求必须在 HTTPS 下才能运行。(其实好多API都须要HTTPS的支持)
  2. 资源路径为根目录的绝对路径。最大做用域 (scope),为资源路径。
    https://www.lilnong.top/static/js/sw-20190621.js的最大做用路径为/static/js/
  3. 为了便于本地开发,localhost 也被浏览器认为是安全源。
  4. 在已经支持 serivce workers 的浏览器的版本中,不少特性没有默认开启。若是你发现示例代码在当前版本的浏览器中怎么样都没法正常运行,你可能须要开启一下浏览器的相关配置:
    Firefox Nightly: 访问 about:config 并设置 dom.serviceWorkers.enabled 的值为 true; 重启浏览器;
    Chrome Canary: 访问 chrome://flags 并开启 experimental-web-platform-features; 重启浏览器 (注意:有些特性在Chrome中没有默认开放支持);
    Opera: 访问 opera://flags 并开启 ServiceWorker 的支持; 重启浏览器。

service worker 声明周期

  1. 下载web

    1. 首次访问service worker控制的网站或页面时,service worker会马上被下载。
    2. 至少每24小时它会被下载一次。
  2. 安装chrome

    1. 首次下载会尝试安装,
    2. 下载的文件是新的,尝试进行安装
  3. 激活vue-cli

    1. 安装成功后它会被激活
    2. 若是现有service worker已启用,新版本会在后台安装,但不会被激活,这个时序称为worker in waiting
    3. 直到全部已加载的页面再也不使用旧的service worker才会激活新的service worker。新的service worker会被激活(成为active worker)。

咱们页面引入sw.js内容为a。当咱们修改成b
这时候ab都是已经安装完毕的,可是a是当前正在用的。b须要等没有页面在用a,才会进入激活状态。
clipboard.pngsegmentfault

Cache

Cache 为缓存的 Request/Response 对象对提供存储机制。
当前咱们做为 ServiceWorker 生命周期的一部分。尽管它被定义在 service worker 的标准中, 可是它没必要必定要配合 service worker 使用。也暴露在 window 做用域下的。api

  1. Cache.add(request)
    request 是一个字符串类型的 URL。如cache.add('https://www.lilnong.top/static/css/normalize-8.0.0.css')
    功能上等于调用 fetch(), 而后使用 Cache.put()response 添加到 cache 中。
  2. Cache.addAll(requests)
    功能同上,只不过入参为字符串数组
  3. Cache.match(request, options)
    返回一个 Promise 对象,resolve 的结果是跟 Cache 对象匹配已经缓存的请求。
    requres 同上,是要匹配的 URL
    options 以下

    1. ignoreSearch: 设置是否忽略url中的query。该选项默认为 false
    2. ignoreMethod: true匹配时就不会验证 Request 对象的 http 方法 (一般只容许是 GETHEAD 。) 该参数默认值为 false。
    3. ignoreVary: 为 true 时匹配不进行 VARY 部分的匹配。例如,若是一个URL匹配,此时不管Response对象是否包含VARY头部,都会认为是成功匹配。该参数默认为 false。
    4. cacheName: 一个 DOMString ,表明一个具体的要被搜索的缓存。注意该选项被 Cache.match()方法忽略。
  4. Cache.matchAll(request, options)
    同上,返回一个Promise 对象,resolve的结果是跟Cache对象匹配的全部请求组成的数组
  5. Cache.put(request, response)
    人为的,为一个URL设置response
  6. Cache.delete(request, options)
    搜索条目。若是找到,则删除该Cache 条目,而且返回一个resolvetruePromise对象;若是未找到,则返回一个resolvefalsePromise对象。
  7. Cache.keys(request, options)
    返回一个Promise对象,resolve的结果是Cache对象key(request 对象)组成的数组。

ServiceWorker 的使用

  1. serviceWorkerContainer.register() 来注册
  2. 注册成功的话,会开启另外一个线程来作这件事。与咱们的网页是互不相干的。
  3. service worker 如今能够接收事件。
  4. service worker 控制的页面打开后会尝试去安装 service worker
  5. 最早发送给 service worker 的事件是安装事件(在这个事件里能够开始进行填充 IndexDB和缓存站点资源),让全部资源可离线访问。
  6. oninstall 事件的处理程序执行完毕后,能够认为 service worker 安装完成了。
  7. service worker 安装完成后,会接收到一个激活事件 onactivate 主要用途是清理先前版本的 service worker 脚本中使用的资源。
  8. Service Worker 如今能够控制页面了,但仅是在 register() 成功后的打开的页面。

ServiceWorker 的注册

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw-test/sw.js', { scope: '/sw-test/' }).then(function(reg) {
    // registration worked
    console.log('Registration succeeded. Scope is ' + reg.scope);
  }).catch(function(error) {
    // registration failed
    console.log('Registration failed with ' + error);
  });
}

微信公众号

clipboard.png

总结

测试路径
https://www.lilnong.top/stati...

  1. https
  2. SW 经过fetch来实现代理浏览器请求。
  3. SW 注册以后会尝试安装。可是激活须要等下次(没有再用的资源了)
  4. SW 要注意他限制的域
  5. importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js'); 是一个封装包
  6. vue-cli也有一些webpack支持的工具

    1. @vue/pwa
    2. @vue/cli-plugin-pwa
  7. 参数中的request能够是

    1. url 好比"https://www.lilnong.top/static/project/pwa-20190625/index.5.html"
    2. 也能够是Request对象。

      1. 能够直接用于保存(put),查找(match),添加(add)
      2. 能够用于fetch

资料

  1. Service_Worker_API --mdn
  2. Service Workers --mdn
  3. cache --mdn
  4. AppCache --mdn
    这个内容我以为不用再关心了 <html manifest="example.appcache">
  5. 前端每周清单半年盘点之 PWA 篇 ---王下邀月熊_Chevalier
  6. 傻傻分不清的Manifest
  7. PWA之 workbox 学习
  8. 初探PWA
相关文章
相关标签/搜索