PWA 落地实践
[[toc]]
谷歌发的协议,苹果目前不支持,但是可以根据 manifest.json 文件能读出来部分配置
项目需求,需要在html5页面中实现,添加PC端桌面或者移动端桌面按钮的功能。经过调研,通过渐进式web应用pwa(Progressive Web Apps)实现添加到主屏幕中(Add to Home Screen,简称 A2HS),是现代智能手机浏览器中的一项功能,能够快捷的web页面添加到主屏幕中,通过快捷方式,单击快速访问。
PWA 中两个角色
1. Service Worker
- 功能:Service Worker 是一个在后台运行的脚本,主要用于控制网络请求、管理缓存、实现离线功能、推送通知等。它在用户关闭页面后依然可以运行,帮助 PWA 提供类似原生应用的体验,如离线支持和后台数据同步。
- 工作原理:Service Worker 拦截网络请求,可以决定是使用缓存的数据,还是从网络获取更新的内容,确保应用能够在无网络连接时也正常工作。
2. Web App Manifest
- 功能:Web App Manifest 是一个 JSON 文件,定义了 PWA 的基本元数据,如应用的名称、图标、启动 URL、主题颜色等。它用于配置 PWA 的外观和行为,特别是在用户将应用添加到主屏幕时,使其像原生应用一样运行。
- 作用:通过 Web App Manifest,用户可以在设备上“安装”你的应用(例如,添加到手机的主屏幕上),并获得类似于原生应用的启动体验。
有这个文件,在pc端已经支持加桌功能,只不过没有离线,推送能功能。
原生PWA 配置
PWA 必须在 HTTPS 环境下运行,因为服务工作线程(Service Worker)等功能需要安全的环境。
1. manifest文件
manifest.json 内容如下:
{ |
然后在head 中添加这个
<link rel="manifest" href="/manifest.json"> |
2. 添加自定义加桌按钮
<button class="add_button_theme" style="display: block"> |
3. 注册Service Worker
推荐使用 register-service-worker 插件,会集成一个钩子函数。
import { register } from 'register-service-worker'; |
原生用法
if ('serviceWorker' in navigator) { |
其中 service-worker.js 文件内容如下,可以在离线状态调取对应数据
一共有三个方法 install 、activate、fetch
install
事件在 Service Worker 首次被安装时触发。通常在此事件中,开发者会预缓存一些静态资源,以确保应用可以在离线时使用。
典型操作:打开缓存并添加文件,如 HTML、CSS、JavaScript 和图像文件。
activate
事件在 Service Worker 被激活时触发,通常用于清理旧的缓存,或者更新缓存内容。当新的 Service Worker 取代旧的 Service Worker 时,这个事件会被触发。
典型操作:删除不再需要的旧缓存,确保新的缓存能够生效。
fetch
事件在页面发起网络请求时触发,开发者可以拦截这些请求,并根据策略(如缓存优先、网络优先等)返回缓存的资源或从网络获取资源。这个事件可以帮助实现离线功能。
典型操作:检查缓存中是否有请求的资源,如果有则返回缓存内容,否则通过网络请求资源。
const CURRENT_CACHE_NAME = 'm_web_dev_v1.1'; // 存储的key |
4. 加载事件beforeinstallprompt
let deferredPrompt; |
判断是否加桌
beforeinstallprompt
事件本身不能直接判断当前应用是否已经被添加到桌面上。它的作用是捕获用户的 PWA 安装提示(通常是在浏览器判断 PWA 可以安装的时候触发)。如果你想判断应用是否已经被添加到桌面,通常需要结合其他方法来实现。
判断是否已被添加到桌面的常见方法:
使用
window.matchMedia()
可以通过检查显示模式来推测应用是否在桌面上运行。例如:if (window.matchMedia('(display-mode: standalone)').matches) {
console.log('The app is running as a standalone PWA');
} else {
console.log('The app is not running as a standalone PWA');
}navigator.standalone
(仅 iOS Safari 支持) 在 iOS Safari 中,你可以使用navigator.standalone
来检查是否运行在独立模式中:if (window.navigator.standalone) {
console.log('The app is running as a standalone PWA on iOS');
} else {
console.log('The app is not running as a standalone PWA on iOS');
}
这两种方法可以帮助你判断应用是否已被添加到桌面上运行。
5. 最终实现效果如下图所示:
目前很多app 都会禁止生成PWA, 比例微信 facebook 飞书等。
如果需要,可以添加 Web Push 通知功能。使用 Push API
和 Notification API
来实现推送通知。
@vue/cli-plugin-pwa
https://github.com/vuejs/vue-cli/tree/dev/packages/vue/cli-plugin-pwa
@vue/cli-plugin-pwa
是 Vue CLI 提供的一个插件,专门用于为 Vue 应用添加 PWA(Progressive Web App)功能。这个插件集成了 Web App Manifest、Service Worker 等核心功能,并提供了一些开箱即用的配置,方便开发者将 Vue 应用转换为 PWA。
主要功能:
自动生成 manifest.json
文件,包含应用名称、图标、启动 URL、主题颜色等信息。
可以通过 vue.config.js
配置来自定义 manifest 的内容。
配置 vue.config.js
文件:
module.exports = { |
Workbox 提供的两种模式
GenerateSW
(默认模式):- 在默认情况下,
@vue/cli-plugin-pwa
使用GenerateSW
模式。这种模式会自动生成一个完整的 Service Worker 文件,并根据你在vue.config.js
中配置的选项(如缓存策略、预缓存文件等)来管理应用的缓存。开发者无需手动编写 Service Worker,插件会为你处理大部分的工作。
- 在默认情况下,
InjectManifest
(自定义模式):- 如果你需要完全控制 Service Worker 的逻辑,比如自定义缓存策略、处理后台同步、管理复杂的推送通知等,可以使用
InjectManifest
模式。 - 在
InjectManifest
模式下,你需要手动编写一个 Service Worker 文件(通常命名为src/my-service-worker.js
或其他路径),然后 Workbox 会在构建过程中将一些基础的 Workbox 运行时代码注入到你编写的 Service Worker 中。这意味着你可以编写自己的 Service Worker 逻辑,同时利用 Workbox 的部分功能。
- 如果你需要完全控制 Service Worker 的逻辑,比如自定义缓存策略、处理后台同步、管理复杂的推送通知等,可以使用
在 InjectManifest
模式下,@vue/cli-plugin-pwa
不会自动生成 service-worker.js
文件。相反,它允许你自己编写自定义的 service-worker.js
文件,然后通过 Workbox 将预缓存逻辑注入到你的自定义 Service Worker 中。
InjectManifest
模式的工作原理
构建时,Workbox 会自动注入额外的代码,以实现预缓存和其他功能
- 预缓存的文件列表
- Workbox Runtime 代码注入
- 使用的 Workbox 功能
self.__WB_MANIFEST 里面包括所有的静态资源
- 自定义 Service Worker 文件:
- 你需要手动编写
service-worker.js
文件。这个文件可以包含你自己定义的缓存策略、事件监听器等逻辑。
- 你需要手动编写
- Workbox 注入预缓存逻辑: 插件会继承很多功能
InjectManifest
模式会将 Workbox 的预缓存逻辑注入到你自定义的service-worker.js
文件中。通过配置,你可以定义哪些文件需要预缓存(例如静态资源),但不会完全覆盖你的自定义逻辑。
- 手动注册 Service Worker:
- 在这种模式下,你仍然需要手动注册 Service Worker,确保浏览器能够找到并激活你的
service-worker.js
文件。
- 在这种模式下,你仍然需要手动注册 Service Worker,确保浏览器能够找到并激活你的
Web Share API
延伸其他API
Web Share API 和 PWA 一样是一项由古哥提出的草案,现还未被纳入 W3C。通过 Web Share API,用户可以方便地将内容或数据分享到应用中。
不过,现在只有安卓 Chrome 55 以上支持 Web Share API。另外,要使用分享功能,还要满足以下几点:
- 网站必须基于 HTTPS
- 注册 Origin Trial,并将生成的 token 加入页面 meta 中
- 提供 text 或 url 中的一项,且值必须为字符串
- 分享事件必须由用户事件触发
满足了这些剩下的就很简单了,只需监听用户事件,然后将需要分享的内容传递给 Web Share API 就可以了。
// CommonService.js |