pwa的checkList
https://developers.google.com/web/progressive-web-apps/checklist
基础检查
- HTTPS
- 响应式设计
- 首页是被离线的 mainfest
- 可以添加到首屏 mainfest
- 3G网络下10秒内完成加载 serviceworker
- 每一个页面都有一个URL
- 页面跳转不受网络影响 spa
技术准备
- fetch
- web worker
- service worker [ cache API ]
- Push Notification
支持情况
https://ispwaready.toxicjohann.com/
ios
- 最新版本支持fetch
- 15年的5年计划支持 service worker
The Service Worker Lifecycle
Service Worker 从注册开始需要先 install, 如果 install 成功, 接下来需要 activate, 然后才能接管页面。但是如果页面被先前的 Service Worker 控制着, 那么它会停留在 installed(waiting) 这个阶段等到页面重新打开才会接管页面, 或者可以通过调用 self.skipWaiting() 方法跳过等待。所以一个 Service Worker 脚本的生命周期有这样一些阶段(从左往右):
registration main.js注册
parsed
注册只之后经历代码解析的过程,
同源 + HTTPS
Install
installing (一般是处理缓存) 成功后 进入 installed 否则 redundant
/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {
if (registration.installing) {
// Service Worker is Installing
}
})
/* In sw.js */
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(currentCacheName).then(function(cache) {
return cache.addAll(arrayOfFilesToCache);
})
);
});
如果是等待交接到页面的时候,
/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {
if (registration.waiting) {
// Service Worker is Waiting
}
})
activing
If there is no current active worker already
If the self.skipWaiting() method is called in the Service Worker script
If the user has navigated away from the page, thereby releasing the previous active worker
If a specified period of time has passed, thereby releasing the previous active worker
actived
代理 fetch & message
Service Worker 脚本最常用的功能是截获请求和缓存资源文件, 这些行为可以绑定在下面这些事件上:
install 事件中, 抓取资源进行缓存
activate 事件中, 遍历缓存, 清除过期的资源
fetch 事件中, 拦截请求, 查询缓存或者网络, 返回请求的资源
Redundant
安装失败
active 失败
被新的 service Worker 替代的pre service worker
消息通知
hai
限制
- 处于安全原因, Service Worker 脚本的作用范围不能超出脚本文件所在的路径。比如地址是 "/sw-test/sw.js" 的脚本只能控制 "/sw-test/" 下的页面。
工具
webpack 生成静态文件的 list https://github.com/goldhand/sw-precache-webpack-plugin
mainfast 生成页面 https://app-manifest.firebaseapp.com/
pwa checkList https://developers.google.com/web/progressive-web-apps/checklist
实战代码块
- 降级
if (支持SW) {
fetch(开关接口)
.then(() => {
if (降级) {
// 注销所有已安装的 SW
} else {
// 注册 SW
}
})
}
安装
更新缓存
waitUntil 如果执行失败不会触发 状态不会进行变化
this.addEventListener('activate', function(event) {
var cacheWhitelist = ['v2'];
event.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (cacheWhitelist.indexOf(key) === -1) {
return caches.delete(key);
}
}));
})
);
});
- 处理请求
缓存优先策略
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});
错误处理
unhandledrejection
self.addEventListener('error', event => {
// 上报错误信息
// 常用的属性:
// event.message
// event.filename
// event.lineno
// event.colno
// event.error.stack
})
self.addEventListener('unhandledrejection', event => {
// 上报错误信息
// 常用的属性:
// event.reason
})
与Hy对比
贺老(贺师俊)曾说过:从纯 Web 到纯 Native,之间有许多可能的点
js权限更大,更加灵活。
- 控制缓存的更新
- 控制版本更新(service.js的更新)提示用户更新 还是静默更新
更加开放更自由
- 通用的标准
- 去平台化
限制
- HTTPS
- chrome40+
结合更不错的选择
PWA 的背后并不是某一家或两家公司,而是整个 web 社区与整个 web 规范。正是因为这种开放与去中心化的力量,使得万维网(World Wide Web)能够成为当今世界上跨平台能力最强、且几乎是唯一一个具备这种跨平台能力的应用平台。
PWA 还继承了 web 应用的另外两大优点:无需先付出几十兆的下载安装成本即可开始使用,以及不需要经过应用超市审核就可以发布新版本。所以,PWA 可以称得上是一种「流式应用(Streamable App)」与「常青应用(Evergreen App)」
参考资料
the-service-worker-lifecycle
offline cookbook
safrai notification
Push API