渐进式 Web 应用使用入门

最近,关于渐进式 Web 应用的讨论非常热烈。它们仍然是一种相对较新的模型,但其原则同样可以增强使用原生 JS、React、Polymer、Angular 或任何其他框架构建的应用。在本文中,我将总结一些选项和参考应用,帮助您立即开始构建自己的渐进式 Web 应用。

什么是渐进式 Web 应用?

请务必记住,渐进式 Web 应用可在任何地方运行,但在现代浏览器中运行效果更佳。渐进增强是该模型的核心。

Aaron Gustafson 将渐进增强比作花生 M&M 巧克力豆。花生是您的内容,巧克力涂层是您的展示层,而 JavaScript 则是硬糖壳。此图层的颜色可能会有所不同,并且体验可能会因所用浏览器的功能而异。

您可以将糖果外壳视为许多渐进式 Web 应用功能可以存在的地方。它们是结合了网页和应用各自优势的体验。用户首次在浏览器标签页中访问这些应用时,无需安装即可使用。

随着用户通过重复使用与这些应用建立关系,他们会使糖果外壳变得更甜 - 在慢速网络连接上加载速度非常快(得益于 Service Worker),发送相关的推送通知,并在用户的主屏幕上提供一流的图标,可将其加载为全屏应用体验。他们还可以利用智能 Web 应用安装横幅。

Web 应用安装横幅(用于提高互动度)、从用户的主屏幕启动、Chrome for Android 中的启动画面、通过 Service Worker 离线运行

渐进式 Web 应用

  • 渐进式 - 适用于每一位用户,无论用户选择使用何种浏览器,因为它们在构建时采用渐进增强作为核心宗旨。
  • 自适应 - 适合任何设备类型、桌面设备、移动设备、平板电脑或未来可能出现的任何设备。
  • 连接性独立 - 借助 Service Worker 增强,可在离线或低质量网络上运行。
  • 应用式 - 使用应用 shell 模型提供应用式导航和互动。
  • 新鲜 - 得益于 Service Worker 更新流程,始终保持最新状态。
  • 安全 - 通过 TLS 提供,可防止窥探并确保内容未被篡改。
  • 可检测到 - 借助 W3C 清单和服务工作线程注册范围,可被识别为“应用”,从而让搜索引擎能够找到它们。
  • 可再互动 - 通过推送通知等功能,轻松实现再互动。
  • 可安装 - 允许用户在主屏幕上“保留”他们认为最实用的应用,而无需通过应用商店。
  • 可链接 - 通过网址轻松分享,无需复杂安装。

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

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

这种模型的“渐进式”特性有一个好处,那就是随着浏览器供应商提供更好的支持,功能可以逐步解锁。当然,Pokedex 等渐进式 Web 应用在 Android 版 Opera 中也能很好地运行,但在实现方面有一些显著差异:

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

如需深入了解渐进式 Web 应用,请阅读 Alex Russell 介绍这些应用的博文。Paul Kinlan 还为渐进式 Web 应用创建了一个非常实用的 Stack Overflow 标签,值得一探究竟。

原则

Web 应用清单

清单可让您的 Web 应用在用户的主屏幕上呈现更接近原生应用的外观。它允许应用以全屏模式启动(不显示网址栏),提供对屏幕方向的控制,并且在 Android 上的最新 Chrome 版本中支持为地址栏定义启动画面和主题颜色。它还用于定义一组图标,这些图标按尺寸和密度进行分类,用于上述启动画面和主屏幕图标。

添加到主屏幕、从主屏幕启动以及全屏应用式体验。

您可以在 Web Starter Kit 和 Google Chrome 示例中找到示例清单文件。Bruce Lawson 编写了一个清单生成器,Mounir Lamouri 也编写了一个方便的 Web 清单验证器,值得一试。

在我的个人项目中,我依靠 realfavicongenerator 为 Web 应用清单以及在 iOS、桌面设备等平台上使用生成尺寸正确的图标。favicons Node 模块还可以在构建过程中实现类似的输出。

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

如需了解详情,请参阅“网站开发基础”中的在 Chrome for Android 中使用 Web 应用清单创建可安装的 Web 应用。

“添加到主屏幕”横幅

Android 版 Chrome 已经支持将您的网站添加到主屏幕有一段时间了,但最近的版本还支持使用原生Web 应用安装横幅主动建议添加网站。

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

为了显示应用安装提示,您的应用必须:

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

我们提供了许多应用安装横幅示例,涵盖了从基本横幅到更复杂的用例(例如显示相关应用)等各种情况。

用于离线缓存的 Service Worker

Service Worker 是在后台运行的脚本,与网页分开。它会响应事件,包括从其所服务的网页发出的网络请求。Service Worker 的生命周期有意设置得较短。

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

Service Worker 不仅能实现强大的离线缓存功能,还能在用户重复访问您的网站或 Web 应用时实现即时加载,从而显著提升性能。您可以缓存应用 Shell,使其能够离线运行,并使用 JavaScript 填充其内容。

应用 Shell 的 Service Worker 缓存,使其无需网络即可加载

Google Chrome 示例中提供了一套全面的 Service Worker 示例。Jake Archibald 的离线指南是必读内容,如果您不熟悉 Service Worker,我强烈建议您尝试 Paul Kinlan 的您的第一个离线 Web 应用演示。

我们的团队还维护着许多 Service Worker 辅助实用程序和构建工具,我们发现这些工具对于减少设置 Service Worker 的开销非常有用。这些库列在 Service Worker 库中。其中两个主要原因是:

  • sw-precache:一种构建时工具,可生成一个 Service Worker 脚本,用于预缓存 Web 应用 shell
  • 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 尚未公开表示有意实现此功能。

开放网络上的推送通知是 Matt Gaunt 撰写的关于设置推送通知的全面介绍,网站开发基础中也提供了推送通知 Codelab。

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

如果您更喜欢视频,Chrome 团队的 Michael van Ouwerkerk 也制作了一个 6 分钟的推送简介。

分层使用高级功能

请记住,用户体验的“甜度”可能会因查看 Web 应用时所用的浏览器而异。您可以控制硬糖壳。

Web 平台即将推出的其他功能,例如后台同步(即使在 Web 应用关闭时也能与服务器同步数据)和 Web 蓝牙(用于从 Web 应用与蓝牙设备通信),也可以通过这种方式分层到渐进式 Web 应用中。

Chrome 中已启用一次性后台同步,Jake Archibald 制作了一个视频,展示了他的离线维基百科应用,并撰写了一篇文章,演示了该功能的实际应用。如果您有兴趣试用 Web Bluetooth API,François Beaufort 还提供了许多 Web Bluetooth 示例。

框架友好

您完全可以将上述任何原则应用于您正在构建的现有应用或框架。在构建渐进式 Web 应用时,还应牢记其他一些原则,例如以用户为中心的 RAIL 性能模型和基于 FLIP 的动画。

我希望在 2016 年,我们将看到越来越多的样板和种子项目自然地将对渐进式 Web 应用的支持作为核心功能。在此之前,将这些功能添加到您自己的应用中并不难,而且我认为非常值得一试。

架构

渐进式 Web 应用模型有不同的“全方位”级别,但一种常见的方法是围绕应用 Shell 构建它们。这不是硬性要求,但确实有诸多好处。

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

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

Jeremy Keith 最近评论说,在这种类型的模型中,也许不应将服务器端渲染视为后备,而应将客户端渲染视为增强。这个反馈很中肯。

在应用 Shell 模型中,应尽可能使用服务器端渲染,并应将客户端渐进式渲染作为一种增强功能,就像我们在支持 Service Worker 时“增强”体验一样。最终可以通过多种方式来实现这一目标。

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

入门样板

应用 Shell

在 GitHub 上查看

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

由于该模型涵盖客户端和服务器端两部分,且涉及的内容相当多,因此您需要一些时间来熟悉代码库。否则,它就是我们目前最全面的渐进式 Web 应用起点。文档将是此项目的下一个重点。

Polymer 入门套件

在 GitHub 上查看

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

Polymer starter kit 显示内置的渐进式 Web 应用功能

当前版本的 PSK 缺少对一些更高级性能模式(例如应用 Shell 模型、异步加载)的支持,这些模式在一些渐进式 Polymer Web 应用中可以找到。

我们的目标是在 2016 年尝试将这些模式融入 PSK,但有关这方面的早期实验可以在 Rob Dodson 的 Polymer Zuperkulblog 应用和 Eric Bidelman 的精彩 Polymer Perf Patterns 演讲中找到。

Web Starter Kit

在 GitHub 上查看

我们为新原生项目提供的预设起点包含以下渐进式 Web 应用功能:

  • Web 应用清单
  • Android 版 Chrome 启动画面
  • 得益于 sw-precache 的 Service Worker 预缓存

如果您偏好使用原生 JS/ES2015,并且无法使用 Polymer,Web Starter Kit 可能会非常有用,您可以将其作为参考点,重复使用或借鉴其中的代码段。

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

社区成员已经构建了许多开源渐进式 Web 应用,其中既有使用 JS 库和框架的应用,也有不使用 JS 库和框架的应用。如果您需要灵感,以下代码库可能会对您有所帮助。这些应用本身也相当出色。

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

Vanilla JavaScript

Polymer

回应

  • iFixit(作者:Jeff Posnick)- 使用 sw-precache 缓存应用 shell(幻灯片)

Virtual-DOM

  • Nolan Lawson 开发的 Pokedex - 采用“在 Web Worker 中执行所有操作”方法来帮助实现渐进式渲染的出色渐进式 Web 应用。(文字说明)

Angular.js

  • Kenneth Auchenberg 开发的 Timey.in - 也使用 sw-precache 进行资源预缓存

结语

如前所述,渐进式 Web 应用仍处于起步阶段,但现在正是尝试其背后方法并了解它们如何应用于您自己的 Web 应用的激动人心的时刻。

Paul Kinlan 目前正在规划有关渐进式 Web 应用的网站开发基础指南,如果您对希望涵盖的领域有任何意见,请随时在帖子中发表评论。

深入阅读