在前端愈来愈重的这个时代,页面加载速度成为了一个重要的指标。对于这个问题,业界也有一些解决方案。css
其实在两年前内部就对这块内容作过调研了。appCache
方案?PWA
方案?可是最后都没选择。
以前看代码,发现是 localstroage
存代码,若是有就拿 localstroage
去用。省去了这一部分加载的时间。
上个同事离职了。当时的调研结果我也忘了。只能再开始新一轮的调研,我选择的是 PWA
方案。(若是说是网速拖慢了加载速度,那么个人网页能够离线访问不就速度起飞了?)
网上的资料不多。我但愿我能够写一篇帮助下一个想使用 PWA
方案的人。html
Service worker
是一个注册在指定源和路径下的事件驱动worker
。前端
Service worker
运行在worker
上下文,所以它不能访问DOM。不一样于主线程,它运行在其余线程中,因此不会形成主线程阻塞。它设计为彻底异步,同步API(如XHR和localStorage)不能在service worker中使用。vue
Service workers
本质上充当Web应用程序(服务端)与浏览器(客户端)之间的代理服务器。
能够提供有效有效的离线体验,拦截网络请求。还能够推送通知。webpack
Service Workers
要求必须在 HTTPS
下才能运行。(其实好多API
都须要HTTPS
的支持)scope
),为资源路径。https://www.lilnong.top/static/js/sw-20190621.js
的最大做用路径为/static/js/
localhost
也被浏览器认为是安全源。serivce workers
的浏览器的版本中,不少特性没有默认开启。若是你发现示例代码在当前版本的浏览器中怎么样都没法正常运行,你可能须要开启一下浏览器的相关配置:about:config
并设置 dom.serviceWorkers.enabled
的值为 true
; 重启浏览器;chrome://flags
并开启 experimental-web-platform-features;
重启浏览器 (注意:有些特性在Chrome
中没有默认开放支持);opera://flags
并开启 ServiceWorker
的支持; 重启浏览器。下载web
service worker
控制的网站或页面时,service worker
会马上被下载。安装chrome
激活vue-cli
service worker
已启用,新版本会在后台安装,但不会被激活,这个时序称为worker in waiting
service worker
才会激活新的service worker
。新的service worker
会被激活(成为active worker
)。咱们页面引入sw.js
内容为a
。当咱们修改成b
。
这时候a
和b
都是已经安装完毕的,可是a
是当前正在用的。b
须要等没有页面在用a
,才会进入激活状态。segmentfault
Cache
为缓存的 Request
/Response
对象对提供存储机制。
当前咱们做为 ServiceWorker
生命周期的一部分。尽管它被定义在 service worker
的标准中, 可是它没必要必定要配合 service worker
使用。也暴露在 window
做用域下的。api
request
是一个字符串类型的 URL
。如cache.add('https://www.lilnong.top/static/css/normalize-8.0.0.css')
fetch()
, 而后使用 Cache.put()
将 response
添加到 cache
中。Cache.match(request, options)
返回一个 Promise
对象,resolve
的结果是跟 Cache
对象匹配已经缓存的请求。requres
同上,是要匹配的 URL
options
以下
ignoreSearch
: 设置是否忽略url
中的query
。该选项默认为 false
。ignoreMethod
: true
匹配时就不会验证 Request
对象的 http
方法 (一般只容许是 GET
或 HEAD
。) 该参数默认值为 false。ignoreVary
: 为 true 时匹配不进行 VARY
部分的匹配。例如,若是一个URL
匹配,此时不管Response
对象是否包含VARY
头部,都会认为是成功匹配。该参数默认为 false。cacheName
: 一个 DOMString ,表明一个具体的要被搜索的缓存。注意该选项被 Cache.match()方法忽略。URL
设置response
Cache
条目,而且返回一个resolve
为true
的Promise
对象;若是未找到,则返回一个resolve
为false
的Promise
对象。resolve
的结果是Cache
对象key
值(request 对象)组成的数组。serviceWorkerContainer.register()
来注册service worker
如今能够接收事件。service worker
控制的页面打开后会尝试去安装 service worker
。service worker
的事件是安装事件(在这个事件里能够开始进行填充 IndexDB和缓存站点资源),让全部资源可离线访问。oninstall
事件的处理程序执行完毕后,能够认为 service worker
安装完成了。service worker
安装完成后,会接收到一个激活事件 onactivate
主要用途是清理先前版本的 service worker
脚本中使用的资源。Service Worker
如今能够控制页面了,但仅是在 register()
成功后的打开的页面。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); }); }
测试路径
https://www.lilnong.top/stati...
https
SW
经过fetch
来实现代理浏览器请求。SW
注册以后会尝试安装。可是激活须要等下次(没有再用的资源了)SW
要注意他限制的域importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js');
是一个封装包vue-cli
也有一些webpack
支持的工具
@vue/pwa
@vue/cli-plugin-pwa
参数中的request能够是
"https://www.lilnong.top/static/project/pwa-20190625/index.5.html"
也能够是Request
对象。
fetch
<html manifest="example.appcache">