一文详解下一代web应用模型—PWA

30次阅读

共计 4361 个字符,预计需要花费 11 分钟才能阅读完成。

去年 apple 在 iOS11.3 的正式更新中,添加了对 service worker 的支持。新的桌面版 Safari 会默认打开 Service Worker。这意味着我们可以通过 Safari 将支持 PWA 的站点像原生 app 一样添加到桌面,并且支持在离线状态下访问。至此,Microsoft, Chrome, Apple 这些浏览器大厂都已全部支持了 PWA。本文将为大家介绍 PWA 的特点、技术核心、创建方法、在项目中的应用和调试技巧。

什么是 PWA
PWA(progressing web app),渐进式网页应用程序,是 google 在 2016 年 GoogleI/ O 大会上提出的下一代 web 应用模型,并在随后的日子里迅速发展。PWA 的目的在于增强 web 体验。从功能上来讲,PWA 首先是一个 web 应用,通过 manifest.json 配置文件以及 Service Worker 来获得 web 加载速度提升,支持离线工作,可被添加主屏幕,全屏执行等特性。这些特性使得 web 应用(尤其是移动设备)体验渐进式接近原生 app。
PWA 的特点
在我们思考 PWA 会为我们带来哪些提升的时候,google 已经为我们总结出了 PWA 的相关特性(可参考:https://developers.google.com…)。
PWA 会为 web 应用带来如下的特点:
Reliable – Load instantly and never show the downasaur, even in uncertainnetwork conditions(可靠的,即使在网络不稳定的条件下,也能够立即加载并且永远不会显示网络瘫痪的页面)
Fast – Respondquickly to user interactions with silky smooth animations and no jankyscrolling.(迅速的,借助于流畅的动画和无卡顿滚动实现快速响应用户的交互)
Engaging- Feel like a natural app on the device, with an immersive user experience.(迷人的,PWA 有着近乎原生 app 般的用户体验)
而在 google 更具体的定义下,PWA 至少应具有这些特性:
渐进式:可以确保每个用户都能够打开网页 响应式:所有硬件设备如手机,pc 都能够完美适配离线应用:支持没有网络的情况下也可以打开网页
app 化:体验近似 app
常更新:经常处于最新的状态
安全:仅服务于 https 协议确保传输内容不会被篡改
可被发现:允许被搜索引擎识别
推送:在没有打开 app 的情况下可以获取到推送信息
可安装:能够像 app 一样被添加到桌面
可跳转:只需一个链接即可访问到你的 web app

PWA 的技术核心
想让自己的 web app 升级成为 PWA,绕不开 PWA 三个关键的技术:

Service Worker
Manifest
Push Notification

下面我会逐一为大家介绍三者的概念
1 ServiceWorker
Service worker 算是 PWA 中的最核心内容了。相比于浏览器默认提供的 workers, service worker 是一种特别的事件驱动的 worker,特别之处在于它的生命周期与当前页面无关,当前页面未关闭也可以退出,当前页面未打开时也可以启动。也就是,service worker 提供了 web 应用通常不具有的离线能力。在网络不稳定的情况下,可以操作 cache 获取数据,并保持页面在离线状态下也能正常显示。(达观数据 施列宇)

你可能会问 AppCache 也具有同样的离线能力,为什么我们不能使用 AppCache 呢?实际上 AppCache 这项技术本身存在更新,存储大小,路径问题。在多页面应用方便,AppCache 还存在着明显的缺陷。而 Service Worker 可以很好的规避这些问题。
Service Worker 的启用条件是 1. 必须是 https 协议或者 localhost 环境下,2.. 浏览器支持。有了这两个先决条件,我们就可以使用 Service Worker 进行 PWA 开发了。

Service Worker 兼容性目前进展
生命周期是 Service Worker 中比较复杂的一部分了,如果不能了解它的整个周期,在使用过程中,你可能会有一种失控的感觉。
Service Worker 的生命周期包含六种状态:parsed, installing, installed. activating, activated, redundant。状态之前的转换过程可以用一张图来表达。Service Worker 的生命周期
Parsed(解析成功): 页面注册 Service Worker 时,浏览器解析脚本并获取入口点。解析成功,就可以访问 serviceworker 对象了。
Installing(正在安装):Service Worker 在解析完成后,浏览器会进行安装。如果安装失败会直接进入到 redundant(废弃) 状态。(达观数据 施列宇)
Installed/Waiting(安装成功 / 等待状态): 如果 ServiceWorker 成功安装,Service Worker 会处于等待状态,等待事件响应。
Activating(正在激活): 处于等待状态下的 Service Worker 如果感知到以下几件事儿,将会进入 activating 状态中:1.Service Worker 脚本中 self.skipWaiting() 方法被调用;2. 用户已关闭 service worker 作用域下的所有页面;3. 页面超时。Acticating 失败也会使 Service Worker 进入 Rendundant 状态。
Activated(激活成功): 激活成功状态。
Redundant(废弃): 废弃状态,Serivce Worker 处于这个状态就会停止工作,需要开发者去检查哪一个环节出了问题。
2 Manifest(应用清单)
PWA 提供了一个 manifest.json 清单文件来向浏览器暴露 web 应用的元数据,包括名称,icon 的 url 等。以备浏览器使用,比如在添加至主屏或推送通知时暴露给操作系统,从而增强 web 应用于操作系统的集成能力。
Manifest 在 PWA 中的作用大致有:

将 PWA 添加至手机屏幕上
在 app 中全屏启动,不显示地址栏
控制屏幕横竖屏
定义 PWA 启动画面
设置应用的启动方式,是从主屏幕启动还是从 URL 启动
设置添加屏幕上的应用程序的基本属性,如名称,图标

3 Push Notification(消息推送)Service worker 中提供了消息推送的功能。消息推送在原生 app 或者 hybird app 中已不鲜见。消息推送到页面,意味着页面预先知道有些事情要发生,并把这些事情做好。比如,提前准备好页面需要的资源。推送的服务器,chromium 默认使用的是 GCM/FCM,目前由于某些原因还无法在国内进行访问,国内暂时也没有浏览器厂商支持标准的推送服务。
创建一个简单的 PWA
介绍了 PWA 使用到的核心技术,下面我们来创建一个简单的 PWA。在使用 Service 之前,需要先判断宿主对象 navigator 中是否含有 servicerWorker 对象。如果存在,则可以通过 serviceWorker 对象的 register 方法进行注册。
注册 Service Worker
注册过程中,浏览器会解析 serviceWorker 注册文件,在此期间出现任何错误,service Worker 都会进入 Redundant 状态。(达观数据 施列宇)
Service Worker 成功执行,install 事件就会被激活,install 完成后,service worker 进入就绪状态,可以进行使用了。

install 事件预处理安装逻辑,使用 skipWaiting 方法让 service worker 直接进入 activating 状态
service worker 对象监听 fetch 对接,在此觉得是否需要使用 service worker 缓存文件亦或是原地址内容。

使用 caches.match 方法判断当前 request 是否为已缓存内容
除此之外,我们也需要及时将过期的静态资源清除掉,当 web 更新,某些文件添加了新的版本号,可以通过 activate 事件回调,清除掉过期资源。然后使用 clients.claim 方法取得页面控制权,这样新页面打开则会使用新的 service worker, 旧的 service worker 对象则会进入 redundant 状态。

使用 activate 事件处理过期资源
这样一个支持 PWA 的 web app 已经搭建起来了,刷新页面后可以从 chrome network 中看到几个缓存的静态资源来源是 from ServiceWorker。

从 network 中看出部分资源是从 service worker 加载而来的
在 angular 项目中添加 PWA 支持达观数据使用了 Angular 作为前端技术栈,我们前端技术团队在研究 pwa 支持的同时也考虑了前端项目在 angular 项目中的兼容性。
Angular 在 6.0 版本加入了 PWA 的支持,想要支持 PWA 特性需要先将 angular,angular-cli 升级到 6 +.
使用 ng add @angular/pwa 添加 PWA 特性支持。添加后会检测到 angular.json,ngsw.json,manifest.json 等多个文件被编辑或被创建。其中 ngsw.json 是 angular 的 PWA 特性的配置文件。­(达观数据 施列宇)
使用 ng build –prod –build-optimizer 命令将代码打包,将代码部署后会看到静态资源都来源于 serviceWorker,也就证明 PWA 添加成功了。

使用 chrome 调试 PWA
google 作为 PWA 的推行者,自家的浏览器也最早带上了 PWA 调试工具,方便开发者进行功能调试。开发者通过 F12 打开调试窗口,选择 application,下方会有 service workers 相应的窗口。这里可以看到当前域下有哪些 serviceworker 对象,可以观察到他们当前的状态,service worker 对象文件详情等信息。也可以通过 offline 勾选项切换无网络状态下页面的反应,update on reload 强制每次刷新都重置 service worker 进行 install; Bypass for network 切换不支持 service worker 窗口下的页面呈现状态。可以说都是很棒的调试功能。(达观数据 施列宇)

chrome service worker 调试窗口
大家也可以在 chrome://serviceworker-internals 中了解浏览器中所有的 service worker 状态。
关于作者施列宇:达观数据前端技术专家,负责达观数据毕昇系统,仓颉系统等项目的研发,对数据挖掘在前端产品中落地,前端数据可视化,标准化工程化有着多年的研究。

正文完
 0