PWA 与 Service Worker API 关系
PWA (Progressive Web App) :渐进式web应用,
Service Worker:本质上充当 Web 应用程序、浏览器与网络(可用时)之间的代理服务器
Service Worker API 是实现 PWA应用的重要的浏览器API
什么是渐进式web应用?
既能通过传统的 web 浏览器访问,也能通过浏览器安装到操作系统主屏幕使用的web 应用
通过如下关键的原则来辨别一个web应用是否是一个PWA应用
- Discoverable, 内容可以通过搜索引擎发现。
- Installable, 可以出现在设备的主屏幕。
- Linkable, 你可以简单地通过一个URL来分享它。
- Network independent, 它可以在离线状态或者是在网速很差的情况下运行。
- Progressive, 它在老版本的浏览器仍旧可以使用,在新版本的浏览器上可以使用全部功能。
- Re-engageable, 无论何时有新的内容它都可以发送通知。
- Responsive, 它在任何具有屏幕和浏览器的设备上可以正常使用——包括手机,平板电脑,笔记本,电视,冰箱,等。
- Safe, 在你和应用之间的连接是安全的,可以阻止第三方访问你的敏感数据。
优势、好处
- 减少应用安装后的加载时间, 多亏了 Service Workers来进行缓存, 以此来节省带宽和时间。
- 当应用有可用的更新时,可以仅仅去更新发生改变的那部分内容。与之相反,对于一个原生应用而言,即便是最微小的改动也需要强制用户去再次下载整个应用。
- 外观和使用感受与原生平台更加融为一体——应用图标被放置在主屏幕上,应用可以全屏运行,等。
- 凭借系统通知和推送消息与用户保持连接,对用户产生更多的吸引力,并且提高转换效率。
Service Workers
Service Workers是浏览器和网络之间的虚拟代理。 他们最终解决了前端开发人员多年来一直在努力解决的问题 - 最值得注意的是解决了如何正确缓存网站资源并使其在用户设备离线时可用。
它们的运行在一个与我们页面的 JavaScript 主线程独立的线程上,并且没有对 DOM 结构的任何访问权限。
他们不仅仅提供离线功能,还提供包括处理通知,在单独的线程上执行繁重的计算等。Service workers 非常强大,因为他们可以控制网络请求,修改网络请求,返回缓存的自定义响应,或合成响应。
Tips:Service Workers 只能在安全的上下文中执行(即 HTTPS ),可通过本地修改Host, 或者网络穿透来使用https 进行本地测试
PWA 应用的实现
PWA 应用并不需要重新构建APP或者对现有应用进行重构,它可以基于现有APP进行改造而不会影响现有的业务逻辑
要实现PWA,最基础的是两部分
- .webmanifest 网站资源清单
- sw.js Service Workers 用于缓存的逻辑
一个简单到PWA 目录如下, 除了当中多了 .webmanifest 文件 和 sw.js 外,其余部分和常见到网站目录并无二一致
网站资源清单文件 .webmanifest
配置正确的.webmanifest 文件,可以使得网站可以安装到系统首页,配置正确后, 浏览器到地址栏会出现如下图中到图标(不同浏览器可能表现不一样)
PWA 应用打开浏览器示意图
一个常见到 .webmanifest 文件配置如下,其中大部分配置跟 chrome 浏览器插件 的清单文件类似
{
"name": "js13kGames Progressive Web App", // 网站应用的全名
"short_name": "js13kPWA", // 显示在主屏上的短名
//一两句话解释你的应用的用途
"description": "Progressive Web App that lists games submitted to the A-Frame category in the js13kGames 2017 competition.",
// 一串图标信息 — 源URL,大小和类型。确保包含一些图标,这样有一个最合适用户设备的图标可以被选中
"icons": [
{
"src": "icons/icon-32.png",
"sizes": "32x32",
"type": "image/png"
},
// ...
{
"src": "icons/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
],
// 启动应用的index文档
"start_url": "/pwa-examples/js13kpwa/index.html",
// 应用的显示方式;可以是全屏,独立,最小UI或者浏览器
"display": "fullscreen",
"theme_color": "#B12A34", // UI的主颜色,这是操作系统使用的
"background_color": "#B12A34" // 背景色,用于安装程序时和显示启动画面时
}
使用 Service workers
使用 Service workers缓存文件,以便网站的离线访问以及优化网站加载
-
注册 sw.js
// 注册 sw.js if('serviceWorker' in navigator) { navigator.serviceWorker.register('./pwa-examples/js13kpwa/sw.js'); };
-
监听 install 事件
self.addEventListener('install', (e) => { console.log('[Service Worker] Install'); });
-
添加文件缓存
const cacheName = 'js13kPWA-v1'; const appShellFiles = [ '/pwa-examples/js13kpwa/', '/pwa-examples/js13kpwa/index.html', '/pwa-examples/js13kpwa/app.js', ]; self.addEventListener('install', (e) => { console.log('[Service Worker] Install'); e.waitUntil((async () => { const cache = await caches.open(cacheName); console.log('[Service Worker] Caching all: app shell and content'); await cache.addAll(contentToCache); })()); });
将文件添加到缓存中,以便后续到加载使用
-
拦截请求
self.addEventListener('fetch', (e) => { e.respondWith((async () => { const r = await caches.match(e.request); console.log(`[Service Worker] Fetching resource: ${e.request.url}`); if (r) { return r; } const response = await fetch(e.request); const cache = await caches.open(cacheName); console.log(`[Service Worker] Caching new resource: ${e.request.url}`); cache.put(e.request, response.clone()); return response; })()); });
当后续打开app后,拦截所有请求,如果文件有缓存,则先返回缓存,否则请求新当文件
参考文档
1.Service Worker API
- 渐进式 web 应用介绍
- 通过 Service workers 让 PWA 离线工作
- 让 PWA 易于安装