PWA
mindmap Workbox
可安装
manifest.json
service-workers
生命周期
- 注册,页面触发
- 安装,后台静默
- 激活,下次访问,需要所有 tab 关闭
当更新你的 Service Worker 时,不要重命名它。甚至不要在文件名中添加文件哈希。否则,浏览器将永远无法获取你的 Service Worker 的新版本!
- 需要缓存资源
- 应用核心 JS CSS
- 字体
- 图片
- 关键 HTTP 请求
与小程序区别
小、快、轻,应对原生应用弊端,让 web 具有应用能力 两个生态: 开放、封闭
传统的 HttpCache,让资源在缓存时性能会很好,而 PWA 是让资源非常可靠地缓存起来,让页面性能一直都很好。
激活问题
默认等待激活,需要等页面关闭,这么设计原因是渐近式
How to immediately activate a service worker with vanilla JS | Go Make Thingsvue.js - How to do skipwaiting with register-service-worker in vue app? - Stack Overflow
// vue.config.js
pwa: {
...
workboxPluginMode: 'GenerateSW',
workboxOptions: {
skipWaiting: true
}
},
用 Vue 做 PWA (三):理解生命周期 - AC DustbinVueJs PWA: Notify User about the App Update | skipWaiting ~ 360learntocode
离线包怎么更新?怎么知道需要打开哪个离线包?
后台更新:每次进入一个新页面,异步检查配置文件,是否需要更新。
通过版本号。
- 网页中的主题色设置
<meta name="theme-color" content="#2196F3">
,优先于 manifest.json 中的设置"theme_color": "#2196F3"
使用Service Worker做一个PWA离线网页应用 – 人人网FED博客
缓存策略
5 种,常用的是缓存优先和网络优先
监听 fetch 事件
- 缓存优先——首先查看缓存,当缓存失效时再去访问网络。这一策略适用于资源文件,如字体、样式、图片等
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
return response || fetch(event.request);
})
);
});
在上面的代码中,我们首先从缓存中获取资源,如果缓存中没有资源,则从网络获取资源。如果网络请求失败,则返回一个空响应。
- 网络优先:首先查看网络,当网络失败时应用本地缓存。这一策略适合实时数据,比如获取天气信息的 AJAX 请求。这样每次页面刷新都可以获得最新的天气信息,当离线时会降级到使用本地缓存。并给出离线的提示。
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request)
.then(function(response) {
return response;
})
.catch(function() {
return caches.match(event.request);
})
);
});
在上面的代码中,我们首先从网络获取资源,如果网络请求失败,则从缓存中获取资源。如果缓存中也没有资源,则返回一个空响应。
cache-first
https://developer.chrome.com/docs/workbox/caching-strategies-overview/
结合业务
- 体验接近离线应用,提高 xx 率
- 节省公司资源:与常规缓存相比,能减少多少资源请求?
- 技术复杂度和成本:相较 SSR 低
Issues
离线后只能从入口访问?不能从子页面
ios 12 支持情况
still force reload every time app is shown/hidden now retain cookies after being reloaded (i.e. login possible) forget deep links support localStorage don't support sessionStorage
解决: Switched to localStorage instead of sessionStorage when "standalone" and persist a custom history stack to restore deep links
vite-plugin-pwa
vite-plugin-pwa 的原理就是通过 Vite 的插件机制,自动生成 PWA 所需的 Service Worker 和 Web App Manifest 文件,并将其注入到 HTML 文件中,从而实现 PWA 的离线访问和快速加载。
- [x] 用本地环境起 vite 项目,看产出物
调试
开启日志
https://developer.chrome.com/docs/workbox/troubleshooting-and-logging/#without-a-bundler
webpack 生成配置方法
https://developer.chrome.com/docs/workbox/reference/workbox-webpack-plugin/#type-GenerateSW
workbox v6 核心方法
precaching:用于在 Service Worker 安装期间缓存静态资源的方法,可以通过配置文件来指定要缓存的文件。【首屏依赖文件,一次性,更新文件,缓存即失效?】
routing:用于在 Service Worker 运行期间拦截网络请求并返回缓存响应的方法。可以根据请求的 URL、请求方法和其他条件来匹配请求。【非首屏依赖文件,动态的,资源会很多】
strategies:用于定义缓存策略的方法。Workbox 提供了几种常见的缓存策略,如 Cache First、Network First、Stale While Revalidate 等。
expiration:用于设置缓存的过期时间的方法。可以根据时间或缓存条目数量来设置过期时间。
background sync:用于在离线状态下将数据保存到后台,直到网络恢复时再进行同步的方法。【比如文档场景】
workbox-window:用于在 Web 应用程序中获取 Service Worker 注册对象、访问缓存和发送消息的方法。
api
precacheAndRoute
revision 为 null,表示根据 URL 来,最佳实践是
- html 用 revision,由 hash 生成,因为不能改名
- 其他资源用 hash url
https://developer.chrome.com/docs/workbox/modules/workbox-precaching/
官方示例
参考
饿了么的 PWA 升级实践 - 黄玄的博客 | Hux BlogLavas | 基于 Vue 的 PWA 完整解决方案LavasBeyond SPAs: alternative architectures for your PWA | Web | Google Developers
Trusted Web Activity
Why Progressive Web Apps Are The Future of Mobile Web [2019 Research]