Open yizihan opened 6 years ago
Progressive Web App 渐进式网络应用
用JS编写的文件,能够代理请求,并且能够操作浏览器缓存,通过将缓存的内容直接返回,让请求能够瞬间完成。
浏览器中的JavaScript都是运行在一个单一主线程上的,在同一时间内只能做一件事情。
技术依赖:
在JS主线程(常规的页面的js)注册Service Worker
if('serviceWorker' in navigator) { // 确保页面加载完毕 window.addEventListener('load', () => { // 注册位于/sw.js的Service Worker navigator.serviceWorker.register('/sw.js', {scope: '/'}) // 注册完成 .then((registration) => { console.log('ServiceWorker registration successful with scope: ', registration.scrope); // 整个网站的控制权 }) .catch((err) => { console.log('ServiceWorker registration failed: ', err); }) }) }
在Service Worker安装成功后,install事件被触发。 install事件一般是被用来填充浏览器的离线缓存能力。 当安装成功之后,Service Worker就会激活。
// sw.js this.addEventListener('install', (event) => { event.waitUntil( // caches.open 创建一个版本号为v1的缓存 返回promise caches.open('v1') .then((cache) => { // cache == 版本号为v1的缓存 // 在创建的缓存上调用addAll(),添加需要缓存的资源路径 return cache.addAll([ '/', '/index.html', '/main.css', '/main.js', '/image.jpeg' ]); }) ) });
我们可以在install的时候进行静态资源缓存,也可以通过fetch事件处理回调来代理页面请求从而实现动态资源缓存。
this.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request) .then((response) => { if(response) return response; // 克隆原始请求 var request = event.request.clone(); return fetch(request).then((httpRes) => { // 请求失败时,直接返回失败结果 if(!httpRes || httpRes.status !== 200) { return httpRes; } // 请求成功时,将请求结果缓存起来 var responseClone = httpRes.clone(); caches.open('v1').then((cache) => { cache.put(event.request, responseClone); }); return httpRes; }) }) ) })
install与fetch比较
如果希望在有了新版本时,所有的页面都得到及时自动更新怎么办? 可以在install事件中执行 self.skipWaiting()方法跳过waiting状态,然后直接进入activate阶段。 然后监听activate事件,通过 self.clients.claim()方法,更新所有客户端上的Service Worker。
self.skipWaiting()
self.clients.claim()
self.addEventListener('install', (event) => { // skipWaiting()强制当前处在waiting状态的Service Worker进入activate状态 event.waitUntil(self.skipWaiting()) }); self.addEventListener('activate', (event) => { event.waitUntil( Promise.all([ // 更新客户端 self.clients.claim(); // ??? caches.keys().then((cacheList) => { return Promise.all( // 清理旧版本 cacheList.map((cacheName) => { if(cacheName !== 'v1') { return caches.delete(cacheName); } }) ) }) ]) ) })
手动借助 Registration.update() 更新
Registration.update()
var version = '1.0.1'; navigator.serviceWorker.register('/sw.js').then((reg) => { if(localStorage.getItem('sw_version') !== version) { reg.update().then(() => { localStorage.setItem('sw_version', version); }) } })
Service Worker的使用过程很简单,所处理的事情也相对单一,我们基本上需要做的就是利用这个API做好站点的缓存策略。 在页面脚本中注册Service Worker文件所在的URL,Worker就可以开始激活了,激活后的Service Worker可以监听当前域下的功能性事件,比如资源请求(fetch)、推送通知(push)、后台同步(sync)。 在这一系列的流程中,从Service Worker的注册到消失,经历了生命周期中的不同状态。
生命周期步骤:
参考文章: LAVAS 文档
PWA
Progressive Web App 渐进式网络应用
为什么是渐进式
Service Worker
用JS编写的文件,能够代理请求,并且能够操作浏览器缓存,通过将缓存的内容直接返回,让请求能够瞬间完成。
Service Worker功能和特性:
使用Service Worker
技术依赖:
注册 register
在JS主线程(常规的页面的js)注册Service Worker
安装 install
在Service Worker安装成功后,install事件被触发。 install事件一般是被用来填充浏览器的离线缓存能力。 当安装成功之后,Service Worker就会激活。
自定义请求响应
我们可以在install的时候进行静态资源缓存,也可以通过fetch事件处理回调来代理页面请求从而实现动态资源缓存。
install与fetch比较
自动更新所有页面
如果希望在有了新版本时,所有的页面都得到及时自动更新怎么办? 可以在install事件中执行
self.skipWaiting()
方法跳过waiting状态,然后直接进入activate阶段。 然后监听activate事件,通过self.clients.claim()
方法,更新所有客户端上的Service Worker。手动更新Service Worker
手动借助
Registration.update()
更新Service Worker生命周期
Service Worker的使用过程很简单,所处理的事情也相对单一,我们基本上需要做的就是利用这个API做好站点的缓存策略。 在页面脚本中注册Service Worker文件所在的URL,Worker就可以开始激活了,激活后的Service Worker可以监听当前域下的功能性事件,比如资源请求(fetch)、推送通知(push)、后台同步(sync)。 在这一系列的流程中,从Service Worker的注册到消失,经历了生命周期中的不同状态。
生命周期步骤:
支持的事件
参考文章: LAVAS 文档