背景
随着web前端的广泛应用,web的快速迭代,响应及推广维护成本较低等优点逐渐被认知,为了扩大JavaScript的影响,不同团队及浏览器厂商分别研发了:基于移动端 app 开发的flutter,uniapp,小程序,react-native,electron 等框架,实现了使用 JavaScript 开发移动或桌面应用,获取这些应用的用户粘性,快速响应及用户留存。在2016年google i/o 的next web 提出了 PWA 作为 web 端类比应用的消息推送、接口拦截、离线缓存等概念。
1. 什么是PWA?
PWA(Progressive Web App,渐进式网页应用)是一种理念,使用多种技术来增强 web app的功能,可以让网站的体验变得更好,能够模拟一些原生功能,比如通知推送。在移动端利用标准化框架,让网页应用呈现和原生应用相似的体验。
之所以称为“渐进式”,是因为给网站架设 PWA 并不影响原有的网页(或者说不需要代码层面的重构),这是一个独立的功能,你可以选择性添加该功能。
2. 相关技术支持
Web App Manifest,Service Worker,Notifications API,Cache storage等。
- Web App Manifest:一个 JSON 配置文件,用于定义 PWA 应用程序清单。
- Service Worker:核心技术 ,实现 PWA 离线工作。
- Cache Storage:提供缓存。
- Notifications API:消息通知,实现类似原生APP的消息推送。
Web App Manifest
提供有关应用程序的信息(如名称,作者,图标和描述),目的是将 Web 应用程序安装到设备的主屏幕,为用户提供更快的访问和更丰富的体验。
- 在网站的根目录下(
/),添加一个 Web应用程序清单文件(manifest.json)。 - 在
index.html中加上<link rel="manifest" href="/manifest.json">
详细配置见官方文档:developer.mozilla.org/zh-CN/docs/…
Service Worker
PWA 中的核心技术,实现网页的离线存储与缓存。
- 基于 web worker,但是在 web worker 的基础上增加了离线缓存的能力。
- 本质上充当了 Web 应用程序与浏览器之间的代理服务器。
- 创建有效的离线体验。
- 由事件驱动,具有生命周期。
- 可以访问 cache 和 indexDB。
如何使用
- 注册service worker。如果注册成功,service worker 就在
ServiceWorkerGlobalScope环境中运行, 与主线程相独立,同时没有访问DOM的能力。
/* 判断当前浏览器是否支持serviceWorker */
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}
- 注册之后,触发
install事件
this.addEventListener('install', function(event) {
event.waitUntil(
caches.open('v1').then(function(cache) {
return cache.addAll([
'/sw-test/',
'/sw-test/index.html',
'/sw-test/style.css',
'/sw-test/app.js',
'/sw-test/image-list.js',
'/sw-test/star-wars-logo.jpg',
'/sw-test/gallery/',
'/sw-test/gallery/bountyHunters.jpg',
'/sw-test/gallery/myLittleVader.jpg',
'/sw-test/gallery/snowTroopers.jpg'
]);
})
);
});
- 监听fetch方法
this.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
);
});
Service worker官方文档:developer.mozilla.org/zh-CN/docs/…
使用Service worker官方文档:developer.mozilla.org/zh-CN/docs/…
Cache Storage
Cache API 是一套搭配 PWA serviceworker 赋能的存储机制,来实现请求数据离线功能。与 applicationCache 相似,提供了力度极细的存储控制能力,内容完全由脚本控制。常在 serviceworker 中搭配 Fetch 使用,且同一个 URL 不同 header 可以存储多个 Response。不提供跨域共享,且与HTTP缓存完全隔离。(上文 #监听fetch方法# )
Push && Notification
消息推送与提醒。
- Notification.requestPermission():service worker注册后调用,获得用户授权信息。
- denied:用户拒绝了通知显示。
- granted:用户允许了通知显示。
- default:不知道用户的选择,浏览器行为与denied时相同。
- registration.showNotification():设置提醒内容
// index.js
registerServiceWorker('./sw.js').then(function (registration) {
return Promise.all([
registration,
askPermission()
])
}).then(function (result) {
var registration = result[0];
/* ===== 添加提醒功能 ====== */
document.querySelector('#js-notification-btn').addEventListener('click', function () {
var title = 'PWA即学即用';
var options = {
body: '邀请你一起学习',
icon: '/img/icons/book-128.png',
actions: [{
action: 'show-book',
title: '去看看'
}, {
action: 'contact-me',
title: '联系我'
}],
tag: 'pwa-starter',
renotify: true
};
registration.showNotification(title, options);
});
/* ======================= */
})
消息推送与提醒借鉴文档:www.jianshu.com/p/f9480c35e…
以上是对 PWA 中涉及到的相关技术的介绍。
vue 项目可以轻松引入 PWA, 相关插件有:@vue/cli-plugin-pwa,vite-plugin-pwa等,均已进行二次封装。
相关文档:cli.vuejs.org/core-plugin…
3. 评价与发展
优势:
- 无需安装,无需下载,只要输入网址访问一次,然后将其添加到设备桌面就可以持续使用。
- 发布不需要提交到 app 商店审核,更新迭代版本不需要审核,不需要重新发布审核。
- 现有的web网页都能通过改进成为 PWA,能很快的转型,上线,实现业务、获取流量。
劣势:
- 浏览器对技术支持还不够全面, 不是每一款浏览器都能100%的支持所有 PWA。
- 需要通过第三方库才能调用底层硬件(如摄像头)。
- 国内一些手机生产商在 Android 系统上做了手脚,似乎屏蔽了PWA。
发展情况:
- 基于 Chromium 开发的浏览器 Chrome 和 Opera 已经完全支持 PWA。Google上线了两个新网站,web.dev 和 squoosh.app 都支持 PWA 。squoosh.app/
- 微软将 PWA 带到了 win10,Windows Edge 支持 PWA。
- IOS 11.3发布,IOS 正式开始支持 PWA ,PWA 应用可以放在主屏。
- 国内:饿了么、微博、bilibili、腾讯新闻等都支持 PWA。