渐进式 Web 应用使用入门

艾迪·奥斯曼
Addy Osmani

最近热烈讨论渐进式 Web 应用 (Progressive Web App)。它们仍然是一个相对较新的模型,但它们的原理同样可以增强使用 vanilla JS、React、Polymer、Angular 或任何其他框架构建的应用。在这篇博文中,我将总结一些方法和参考应用,供您立即开始使用您自己的渐进式 Web 应用。

什么是渐进式 Web 应用?

请务必注意,渐进式 Web 应用可以在任何地方使用,但在现代浏览器中是极为强大的。渐进式增强是该模型的基石

亚伦·古斯塔夫森将渐进式增强比作花生 M&M。花生是您的内容,巧克力涂层是您的表现层,而 JavaScript 则是硬糖外壳。该层的颜色可能有所不同,其体验也会因使用该层的浏览器功能而异。

把糖果壳看成是许多渐进式 Web 应用功能可以发挥作用的地方。他们将网络之长与应用的精华融为一体,为用户带来非凡的体验。用户在浏览器标签页中第一次访问时就能体会到它们的好处,而且无需安装。

随着用户不断与这些应用建立关系,他们会让糖果壳变得更加甜蜜 - 在网速较慢时加载速度非常快(这要归功于 Service Worker),发送相关的推送通知,并在用户的主屏幕上显示具有全屏应用体验的一流图标。他们还可以利用智能的网络应用安装横幅

用于互动的 Web 应用安装横幅、从用户主屏幕启动、Android 版 Chrome 中的启动画面、可离线使用 Service Worker

渐进式 Web 应用

  • 渐进式 - 适合使用任何浏览器的所有用户,因为它们作为核心租户采用渐进式增强功能构建而成。
  • 自适应 - 适应任何外形规格,包括桌面设备、移动设备、平板电脑或任何未来设备。
  • 连接无关性 - 可借助 Service Worker 加强离线工作或处理低质量网络的情况。
  • 类似应用 - 使用 App Shell 模型提供应用样式的导航和互动。
  • 持续更新 - 在 Service Worker 的更新进程的帮助下始终保持最新状态。
  • 安全 - 通过 TLS 提供,以防止窥探并确保内容不被篡改。
  • 可发现 - 可被识别为“应用”,这得益于 W3C 清单和 Service Worker 注册范围,让搜索引擎能够找到它们。
  • 可再互动 - 通过推送通知等功能,轻松实现再互动。
  • 可安装 - 让用户不必前往应用商店就能将他们认为最有用的应用“保留”在主屏幕上。
  • 可链接 - 通过网址轻松分享,无需复杂的安装。

渐进式 Web 应用也并非 Chrome(Android 版)所独有。从下图中我们可以看到,Pokedex 渐进式 Web 应用可在 Android 版 Firefox(Beta 版)中正常运行,其早期“添加到主屏幕”功能和 Service Worker 缓存功能正常运行。

可在 Android 版 Firefox 中运行的渐进式 Web 应用

这种模型“渐进式”的优点之一是,随着浏览器供应商不断为这些功能提供更好的支持,相关功能可以逐渐解锁。当然,渐进式 Web 应用(例如 Pokedex)在 Android 上的 Opera 中也表现出色,但实现方式上存在一些明显的差异:

在 Opera for Android 中运行的渐进式 Web 应用

如需更深入地了解渐进式 Web 应用,请阅读 Alex Russell 的原创博文,对它们进行介绍。Paul Kinlan 还为渐进式 Web 应用创建了一个非常有用的 Stack Overflow 标记,值得一试。

原则

Web 应用清单

借助该清单,您的 Web 应用能够在用户的主屏幕上以更接近原生的方式显示。它允许应用以全屏模式启动(不显示网址栏),提供对屏幕方向的控制,并且在较新版本的 Android 版 Chrome 中,支持为地址栏定义启动画面主题背景颜色。它还用于按大小和密度定义一组用于上述启动画面和主屏幕图标的图标。

添加到主屏幕、从主屏幕启动,以及类似于应用的全屏体验。

您可以在 Web Starter KitGoogle Chrome 示例中找到示例清单文件。Bruce Lawson 编写了清单生成器,Mounir Lamouri 也编写了一个实用的网络清单验证器,值得一试。

在我的个人项目中,我依靠 realfavicongenerator 来为 Web 应用清单以及 iOS、桌面设备等设备生成大小正确的图标。favicons Node 模块也可在构建流程中实现类似的输出。

目前,基于 Chromium 的浏览器(Chrome、Opera 等)支持 Web 应用清单,Firefox 正积极开发支持,Edge 也已将其列为考虑中。WebKit/Safari 尚未发布关于其意图的公开信号来实现该功能。

有关详情,请参阅网站开发基础中的带有 Web 应用清单的 Chrome(Android 版)可安装的 Web 应用

“添加到主屏幕”横幅

Android 版 Chrome 暂时支持将您的网站添加到主屏幕,但近期的版本也支持使用原生网络应用安装横幅主动建议添加的网站。

语音备忘录演示应用,该应用在 Android 版 Chrome 中显示网络应用安装横幅提示

为了让应用安装提示显示您的应用,必须满足以下条件:

  • 具备有效的 Web 应用清单
  • 通过 HTTPS 提供(如需获取免费证书,请参阅 letsencrypt
  • 已注册有效的 Service Worker
  • 被访问两次,两次访问之间至少间隔 5 分钟

我们提供许多应用安装横幅示例,从基本横幅到显示相关应用等更复杂的用例,不一而足。

用于离线缓存的 Service Worker

Service Worker 是一种与网页分开在后台运行的脚本。它会对事件做出响应,包括从它所传送的网页发出的网络请求。Service Worker 的生命周期被特意缩短。

它在获得事件时唤醒,并且仅在需要处理时才运行。借助 Service Worker,您可以使用 Cache API 缓存资源,并且可以用于为用户提供离线体验。

Service Worker 功能强大,可以进行离线缓存,不过,由于它们可以为您重复访问网站或 Web 应用,可以实现即时加载,从而显著提升性能。您可以缓存 App Shell,使其能够离线工作,并使用 JavaScript 填充其内容。

应用 Shell 的 Service Worker 缓存,允许其在没有网络的情况下进行加载

Google Chrome 示例上提供了一套全面的 Service Worker 示例。Jake Archibald 的离线实战宝典是必读好书,如果您刚开始使用 Service Worker,我强烈建议您试试 Paul Kinlan 的首个离线 Web 应用演示。

我们的团队还维护了一些 Service Worker 辅助实用程序和构建工具,我们认为这些工具和工具有助于减少获取 Service Worker 的开销。Service Worker 库中列出了这些库。两个主要选项是:

  • sw-precache:一种构建时工具,可生成用于预缓存 Web App Shell 的 Service Worker 脚本
  • sw-toolbox:为不常用的资源提供运行时缓存的库

Jeff Posnick 撰写了一篇关于 sw-precache 的快速入门教程,名为离线优先,快速(使用 sw-precache 模块),以及基于您可能认为有用的同一工具的 Codelab

Chrome、Opera 和 Firefox 都已实现对 Service Worker 的支持,而 Edge 的公开信号表明用户对该功能感兴趣。Safari 通过一名工程师提议的五年计划简要提及了对这项技术的兴趣。

用于吸引用户再互动的推送通知

您可以高效地构建用户可在标签页之外与之互动的 Web 应用。浏览器可以关闭,甚至无需主动使用您的 Web 应用即可与您的体验互动。该功能需要 Service Worker 和 Web 应用清单,以前面总结的一些功能为基础。

Push API 已在 Chrome 中实现,在 Firefox 中处于开发阶段,正在考虑在 Edge 中实现。Safari 尚未提供任何表明他们有意实现此功能的公开信号。

开放 Web 上的推送通知全面介绍了 Matt Gaunt 如何设置推送。Web 基础知识中也提供了推送通知 Codelab

Facebook 移动网站上的 Web 推送通知

Chrome 团队的 Michael van Ouwerkerk 还观看了一段 6 分钟的视频简介,如果您更喜欢视频,可以点击“Push”开始聊天。

对高级功能进行分层

请注意,您的用户体验可能具有不同的“甜蜜度”,具体取决于用户用来查看 Web 应用的浏览器。硬糖的控制权在您的手中。

Web 平台引入的其他功能(例如后台同步(用于在 Web 应用关闭后仍与服务器进行数据同步)和 Web Bluetooth(用于从 Web 应用与蓝牙设备通信)等额外功能也可以这种方式分层到 Progressive Web 应用中。

Chrome 中已启用一次性后台同步,Jake Archibald 也发布了一段离线维基百科应用视频以及展示该应用的文章。如果您有兴趣试用该 API,Francois Beaufort 也提供了许多网络蓝牙示例

与框架兼容

实际上,没有什么可以阻止您将上述任何原则应用于您正在构建的现有应用或框架中。在构建渐进式 Web 应用时,值得注意的一些其他原则包括 RAIL 以用户为中心的性能模型和基于 FLIP 的动画。

我希望在 2016 年,我们会看到越来越多的样板和种子项目在进行自然开发,以支持将渐进式 Web 应用作为一项核心功能。在此之前,向自己的应用添加这些功能的门槛并不高,所以 IMHO 非常值得为之付出努力。

架构

在 Progressive Web App 模型中,“全方位”的机制有不同的级别,但一种常见的方法是围绕应用 Shell 进行架构设计。这并非硬性要求,但有几个好处。

应用 Shell 架构建议缓存应用 Shell(界面),以便它可以离线使用,并使用 JavaScript 填充其内容。对于重复访问,这可让您在没有网络的情况下快速在屏幕上获得有意义的像素,即使您的内容最终来自网络也是如此。这样做会显著提升性能。

应用 Shell 被可视化为分解应用的界面,例如抽屉式导航栏和主要内容区域

Jeremy Keith 最近评论过,在此类模型中,不应将服务器端渲染视为后备方案,而应将客户端渲染视为增强功能。这是公平的反馈。

在 Application Shell 模型中,应尽可能多地使用服务器端渲染,而客户端渐进式渲染也应作为一种增强功能,与我们“增强”支持 Service Worker 时的体验一样。我们最终可以通过多种方法解决这个问题。

我的建议是阅读我们关于架构的文章,并评估如何将相似的原则更好地应用于您自己的应用和堆栈。

样板使用入门

应用 Shell

在 GitHub 上查看

app-shell 代码库包含应用 Shell 架构的几乎完整实现。它有一个使用 Express.js 编写的后端和一个用 ES2015 编写的前端。

它涵盖了模型的客户端和服务器端部分,并且涉及的内容非常多,因此需要一些时间来熟悉代码库。除此之外,它是我们当前最全面的渐进式 Web 应用起点。此项目的下一个重点是 Google 文档。

Polymer 入门套件

在 GitHub 上查看

Polymer Web 应用的官方起点支持以下渐进式 Web 应用功能:

显示内置渐进式 Web 应用功能的 Polymer 入门套件

在某些 Progressive Polymer Web 应用中,当前的 PSK 版本不支持某些更高级的性能模式(例如,应用 Shell 模型、异步加载)。

我们的目标是在 2016 年尝试将这些模式烘焙成 PSK,但您可以在 Rob Dodson 的 Polymer Zuperkulblog 应用中以及 Eric Bidelman 的精彩 Polymer Perf Patterns 演讲中找到与此相关的早期实验。

Web Starter Kit

在 GitHub 上查看

我们针对新 vanilla 项目的初衷,包括下列渐进式 Web 应用功能:

  • Web 应用清单
  • Android 版 Chrome 启动画面
  • 借助 sw-precache 实现 Service Worker 预缓存

如果您更喜欢使用 vanilla JS/ES2015 但无法使用 Polymer,那么 Web Starter Kit 可以作为一个参考点,供您重复使用或窃取其代码段。

使用和不使用框架的渐进式 Web 应用

社区成员已经构建了大量开源 Progressive Web App,无论是否有 JS 库和框架。如果您正在寻找灵感,以下代码库可能可以作为参考。这些应用也实在是太棒了。

使用 React、Polymer、Virtual DOM 和 AngularJS 实现的渐进式 Web 应用

香草 JavaScript

Polymer

回应

  • Jeff Posnick 的 iFixit - 使用 sw-precache 进行 App Shell 缓存(幻灯片)

虚拟 DOM

  • Nolan Lawson 的 Pokedex - 一款出色的渐进式 Web 应用,采用“在 Web Worker 中处理所有事情”方法来帮助实现渐进式渲染。(书面记录

Angular.js

  • Kenneth Auchenberg 的 Timey.in - 还使用 sw-precache 预缓存资源

结语

正如前面提到的,渐进式 Web 应用仍处于起步阶段,但现在是一个激动人心的时刻,您可以试用其背后的方法,看看它们如何应用于您自己的 Web 应用。

Paul Kinlan 目前规划有关渐进式 Web 应用的网页基础知识指南,如果您想了解相关内容的方方面面,请随时在主题帖中留言。

深入阅读