作者:永无止晋

2016年 Google 在 I/O 大会上提出一个 Next Web Generation 的概念 —— PWA 横空出世,2017年始开始流行,目前虽未完全成熟,但越来越火爆,可以预见未来会广为流行。你还在等什么?

一、Hello PWA

PWA(Progressive Web App)[1], 渐进式 WEB 应用,是提升 Web App 的体验的一种方法,给用户原生应用的体验。PWA 可以通过 Service Worker, Manifest 等新技术让站点具备离线可用、添加到桌面、实时消息提醒等功能,从功能和体验上无限接近原生 App。

1.1. 背景

自1990年万维网之父-蒂莫西·约翰·“蒂姆”·伯纳·李爵士,创建了 HTTP、HTML 和 WorldWideWeb (全世界第一个网页浏览器)以来,Web 技术和影响力在以惊人的速度增长。HTML5,CSS3,Webpack,React,VUE,Babel,SPA 等技术的成熟与发展仿佛让 Web 进入了百家争鸣的春秋时期,Web应用能做的事情越来越多,大家对web的希望也越来越高。

但随着移动时代的到来,web 应用因为不能离线访问,没有快捷入口和页面频繁卡顿等开始失宠。除了原生应用因离线能力,瞬时加载和可靠性强等优点爆炸性崛起外,Hybrid ,React Native 等 APP 开发模式似乎也有点如日中天的“赶脚”。作为一名 Web 前端开发工程师已经瑟瑟发抖,你呢? 莫慌,老大哥 Google 的工程师们早就“抖”完了,并在2015年提出2016年推出 PWA ,号称 PWA 将成为 Web 颠覆者的契机。

从上图我们可以看出除了原生功能体验、渲染性能,支持设备底层访问,网络要求等四个方面外, Web App 对比 Native、Hybrid、React Native,还是占据一定优势的。更让人兴奋的是 PWA 一定程度上解决了 Web App 的“劣势”(图中黄色背景部分),让 Web APP 在保留原有优势的基础上渐进式接近原生 App。

1.2. 主要特点&优势

  • 可靠 – 即使在不稳定的网络环境下,也能瞬间加载并展现
  • 快速 – 快速响应,并且有平滑的动画响应用户的操作
  • 粘性 – 像设备上的原生应用,具有沉浸式的用户体验,用户可以添加到桌面

以上列举的是PWA的三个最主要的特点,要想了解所有特点,可到 PWA官网[2] 查看。

1.3. 主要技术

PWA并不是描述一个技术,而是一个技术的合集,包含以下几个主要技术:

1. Service Worker(详见本文第二节);

2.  App Manifest(详见本文第三节);

3. Push API:允许 Web 应用拥有接收服务器并推送消息的能力( Web App 内部的消息推送)。目前已得到安卓和 PC 上新版本主流浏览器的支持,ios平台不兼容;

4、Notifications API:允许 Web 应用向用户显示系统通知。目前已兼容大部分 PC 主流浏览器,尚不兼容移动端浏览器。

5、Background Sync:可延迟发送用户行为,直到用户网络连接稳定。目前几乎不兼容移动端浏览器,PC 上 Firefox、 Chrome、 Safari、 Edge 等浏览器均已兼容。可解决两个常见问题:
– 普通的页面发起的请求会随着浏览器进程的结束/或者 Tab 页面的关闭而终止;
– 无网环境下,没有一种机制能“维持”住该请求,以待有网情况下再进行请求。

二、Service Worker

2.1. 什么是 Service Worker?

将你的网络请求想象成飞机起飞,Service Worker 是路由请求的空中交通管制员。它可以通过网络加载,或甚至通过缓存加载。

空中交通管制员可以延迟甚至改变飞机的降落的机场,Service Worker 的行为方式也是如此,它可以重定向你的请求,甚至彻底停止。如上图所示,Service Worker 在浏览器和后端服务之间起到了“管制员”的作用,它可以让你全权控制网站发起的每一个请求,这为许多不同的使用场景开辟了可能性,离线访问只是其中一种。

2.2. 功能特性

关于 Service Worker 的功能特性,以下几点看似无聊,其实很重要,不妨开发过程遇到问题再回头看看。

  • 要求 HTTPS 环境,开发过程中,一般浏览器也允许 host 为 localhost 或者 127.0.0.1;
  • 运行在它自己的全局脚本上下文中;
  • 不绑定到具体的网页,无法修改网页中的元素,因为它无法访问 DOM;
  • 一旦被 install,就永远存在,除非被手动 unregister;
  • 异步实现,内部大都是通过 Promise 实现,依赖 HTML5 fetch API[3]
  • Service Worker 的缓存机制是依赖 Cache API[4] 实现的;

2.3. 生命周期

Service Worker 包含以下几个生命周期:

  • 正在安装(installing):发生在 Service Worker 注册之后,表示开始安装,触发 install 事件回调指定一些静态资源进行离线缓存, install 事件回调中有两个方法:
    • event.waitUntil():传入一个 Promise 为参数,等到该 Promise 为 resolve 状态为止。
    • self.skipWaiting():执行该方法表示强制当前处在 waiting 状态的 Service Worker 进入 activate 状态。
  • 已安装(installed):安装完成,等待其他的 Service Worker 线程被关闭。
  • 正在激活(activating):处于 activating 状态期间,Service Worker 脚本中的 activate 事件被执行。我们通常在 activate 事件中,清理 cache 中的文件。 activate 回调中有以下两个方法:
    • event.waitUntil():传入一个 Promise 为参数,等到该 Promise 为 resolve 状态为止。
    • self.clients.claim():在 activate 事件回调中执行该方法表示取得页面的控制权, 这样之后打开页面都会使用版本更新的缓存。旧的 Service Worker 脚本不再控制着页面,之后会被停止。
  • 已激活(activated):在这个状态会处理 activate 事件回调 (提供了更新缓存策略的机会)。并可以处理功能性的事件 fetch (请求)、 sync (后台同步)、 push (推送)等。
  • 废弃状态(Redundant):这个状态表示一个 Service Worker 的生命周期结束。进入废弃 ( redundant ) 状态的原因可能为这几种:
    1. 安装 ( install ) 失败
    2. 激活 ( activating ) 失败
    3. 新版本的 Service Worker 替换了它并成为激活状态

2.4. 主要事件

Service Worker 是基于事件的,安装、激活、缓存、通信等操作都是需要在特定事件下操作,包含以下几个主要事件。

2.5. 使用 Service Worker 缓存

上面一小节,我们了解了常用的几个事件,本节让我们一起利用这些事件缓存资源。(看代码的时候注意注释哦)

(1) 注册

首先要注册 Service Worker, 我们需要注册 Service Worker 来启动安装。 sw.js 文件推荐在 HTML 当中引入:

(2) 通过 install 事件做静态缓存

接着我们往 sw.js 文件中添加逻辑,我们先尝试用 install 事件来做静态缓存。

为了帮助大家更好的理解下文的代码,请先熟悉上文生命周期中的几个方法和以下几个 Service Worker 的全局变量:

(3) 通过 fetch 事件使用缓存和处理动态缓存

Service Worker 会拦截浏览器所有请求,并查询当前 cache,如果存在 cache 则直接返回,若不存在,则通过 fetch 方法向服务端发起请求,并返回请求结果给浏览器。

(4) 通过 active 事件更新缓存

当我们将资源缓存后,除非注销 sw.js 或手动清除缓存,否则新的静态资源无法缓存。这个时候在我们可以在 activate 事件中检查 cacheName 是否变化,如果变化则表示有了新的缓存资源,则将原有缓存删除。所以在 sw.js中加入以下代码后,当需要更新缓存时,我们仅仅需要修改 cacheName 就可以了。

除了通过 active 事件更新缓存,我们还可以在注册 Service Worker 的时候借助 Registration.update() 更新。

2.6. 兼容性

2.7. 小结

咳咳咳,关于 Service Worker,本文先聊这么多,后续会有专文跟大家讨论,请持续我们的JDC网站或全栈探索微信公众号。

三、Manifest

3.1. Manifest是什么?

manifest 的目的是将Web应用程序安装到设备的主屏幕,为用户提供更快的访问和更丰富的体验。

3.2. 安装 Web App 到主屏幕条件

  • 站点支持 HTTPS 访问;
  • 站点部署 manifest.json;
  • 站点注册 Service Worker;

3.3. manifest.json

PWA 添加至桌面的功能实现依赖于 manifest.json 文件,一个基本的 manifest.json 文件应包含如下信息:

3.4. 引用manifest.json

manifest.json 配置的 start_url 对应的 html 文件的 head 标签中按如下方式引用即可:

3.5. 使用 manifest 实现 Web APP 的启动页

启动页示例

通过配置 manifest.json 的下列属性,可以很容易的实现上图的 Web App 启动页:

  1. 设置图像和标题:标题则直接取自 name。浏览器会从 icons 中选择最接近 128dp 的图片作为启动画面图像。
  2. 设置启动背景颜色:支持 #ffffff , #fff , white , rgb(255,255,255) 格式,其他不支持,如 rgba 。
  3. 设置启动显示类型:仅当显示类型 display 设置为 standalone 或 fullscreen 时,PWA 启动的时候才会显示启动画面。

3.6. 小结

看到这里,你已经可以动手去把你的 Web APP 添加到桌面啦,由于兼容性问题,建议在 Android 或 PC 上使用 Chrome 浏览器体验。(PC 上需要配置谷歌浏览器,打开“chrome://flags/”中允许Desktop PWAs即可)

写在最后的话

本文旨在和大家一起学习 PWA 的入门知识,分别介绍了 PWA 的现状,特点以及其核心技术 Service Worker 和 Manifest。后续还会有文章和大家一起深入学习 PWA。欢迎各位提出问题和建议,共同成长和进步。 让热爱 Web 的我们一起书写 Web 的未来!

扩展阅读

[1] https://developers.google.com/web/progressive-web-apps/

[2] https://developers.google.cn/web/progressive-web-apps/checklist

[3] https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API

[4] https://developer.mozilla.org/zh-CN/docs/Web/API/Cache

文章来源于 全栈探索 微信公众号,扫描下面二维码关注:

喜欢(5) 评论(4) 分享

Leave a Reply

© 2018 JDC. All Rights Reserved.