我们最近收到了许多关于渐进式 Web 应用的讨论。它们仍然是一种相对较新的模型,但其原则同样可以增强使用原生 JS、React、Polymer、Angular 或任何其他框架构建的应用。在本文中,我将总结一些选项和参考应用,以便您立即开始构建自己的渐进式 Web 应用。
什么是渐进式 Web 应用?
请务必注意,渐进式 Web 应用可在任何地方运行,但在现代浏览器中可发挥更强大的作用。渐进增强是该模型的支柱。
Aaron Gustafson 将渐进增强比作了 M&M 花生巧克力。花生是您的内容,巧克力外壳是您的呈现层,JavaScript 是硬糖壳。此图层的颜色可能会有所不同,体验也可能会因使用该图层的浏览器的功能而异。
您可以将糖果壳视为许多渐进式 Web 应用功能的所在位置。它们将网站和应用的优势完美结合,用户在浏览器标签页中首次访问时,就可以使用这些扩展程序,无需安装。
随着用户通过反复使用与这些应用建立关系,这些应用会让糖果壳变得更加甜美:在网络连接缓慢的情况下快速加载(得益于服务工件),发送相关的推送通知,并在用户的主屏幕上显示一流的图标,以便以全屏应用体验加载这些应用。他们还可以利用智能的网站应用安装横幅广告。
渐进式 Web 应用具有以下特点:
- 渐进式 - 适用于所有用户,无论他们选择的是哪款浏览器,因为这些网站在构建时都以渐进增强为核心理念。
- 自适应 - 适用于任何外形规格,包括桌面设备、移动设备、平板电脑或未来的任何设备。
- 独立于网络连接 - 通过服务工件进行了增强,可在离线或网络质量较差的情况下正常运行。
- 类似应用 - 使用应用 Shell 模型提供应用风格的导航和互动。
- 新鲜 - 借助服务工件更新流程,始终保持最新状态。
- 安全 - 通过 TLS 提供,以防止窥探并确保内容未被篡改。
- 易于发现 - 由于 W3C 清单和服务工件注册范围允许搜索引擎找到它们,因此可识别为“应用”。
- 可再次吸引用户互动 - 通过推送通知等功能轻松再次吸引用户互动。
- 可安装 - 允许用户将自己认为最实用的应用“保留”在主屏幕上,而无需前往应用商店。
- 可链接 - 可通过网址轻松共享,无需进行复杂的安装。
渐进式 Web 应用也不是 Android 版 Chrome 独有的。下方显示了 Pokedex 渐进式 Web 应用在 Firefox for Android(Beta 版)中运行的效果,其中“添加到主屏幕”和服务工件缓存功能均正常运行。
这种“渐进式”模型的一个好处是,随着浏览器供应商提供更好的支持,可以逐步解锁功能。当然,Pokedex 等渐进式 Web 应用在 Android 版 Opera 中也能很好地运行,但在实现方面存在一些显著差异:
如需深入了解渐进式 Web 应用,请阅读 Alex Russell 介绍该概念的原始博文。Paul Kinlan 还创建了一个非常实用的 Stack Overflow 标签,供开发者讨论渐进式 Web 应用相关问题,值得您访问。
原则
Web 应用清单
借助清单,您的 Web 应用可以在用户的主屏幕上呈现更接近原生应用的界面。它允许应用以全屏模式启动(不显示网址栏),提供对屏幕方向的控制,并且在 Android 版 Chrome 的最新版本中,支持为地址栏定义启动画面和主题颜色。它还用于按大小和密度定义一组图标,用于上述启动画面和主屏幕图标。
您可以在 Web Starter Kit 和 Google Chrome 示例中找到示例清单文件。Bruce Lawson 编写了一个清单生成器,Mounir Lamouri 还编写了一个实用的网站清单验证器,值得您了解。
在我的个人项目中,我依赖 realfavicongenerator 来为网站应用清单生成尺寸正确的图标,并在 iOS、桌面设备等平台上使用。favicons Node 模块也可以在构建过程中生成类似的输出。
基于 Chromium 的浏览器(Chrome、Opera 等)目前支持 Web 应用清单,Firefox 正在积极开发支持,Edge 将其列为正在考虑。WebKit/Safari 尚未发布有关其打算实现该功能的意图的公开信号。
如需了解更多详情,请参阅网站开发基础中的在 Chrome for Android 中使用 Web 应用清单创建可安装 Web 应用。
“添加到主屏幕”横幅
Android 版 Chrome 已经支持将您的网站添加到主屏幕一段时间了,但近期版本还支持使用原生Web 应用安装横幅主动建议添加网站。
为了显示应用安装提示,您的应用必须:
- 拥有有效的 Web 应用清单
- 采用 HTTPS 协议(如需免费证书,请参阅 letsencrypt)
- 已注册有效的服务工件
- 获得两次访问,两次访问之间至少间隔 5 分钟
我们提供了许多应用安装横幅广告示例,涵盖基本横幅广告到更复杂的用例(例如显示相关应用)等各种类型。
用于离线缓存的 Service Worker
Service Worker 是指在后台运行的脚本,与网页分开。它会响应事件,包括从其提供的网页发出的网络请求。服务工件的生命周期是故意设为较短的。
它会在收到事件时唤醒,并且仅在需要处理事件时运行。借助服务工件,您可以使用 Cache API 缓存资源,并可用于为用户提供离线体验。
服务工件在离线缓存方面非常强大,但它们还能以即时加载的方式显著提升性能,让用户能够反复访问您的网站或 Web 应用。您可以缓存应用 shell,以便其在离线状态下运行并使用 JavaScript 填充其内容。
Google Chrome 示例中提供了一组全面的 Service Worker 示例。Jake Archibald 的离线食谱是必读之作,如果您刚开始接触服务工作器,强烈建议您试用 Paul Kinlan 的您的第一个离线 Web 应用演示。
我们的团队还维护着许多实用程序和构建工具,这些工具有助于减少设置服务工件的开销。这些库列在服务工作器库中。其中两个主要原因是:
- sw-precache:一种构建时工具,用于生成有助于预缓存 Web 应用 shell 的 Service Worker 脚本
- sw-toolbox:一个库,用于为不经常使用的资源提供运行时缓存
Jeff Posnick 撰写了一篇名为 Offline-first, fast, with the sw-precache module 的 sw-precache 快速入门文章,并提供了一个关于该工具的 codelab,您可能会发现它们很有用。
Chrome、Opera 和 Firefox 都已实现对服务工件的支持,Edge 也已公开表示对该功能感兴趣。Safari 在一位工程师提出的五年计划中简要提及了对此的兴趣。
用于再互动的推送通知
实际上,您可以构建 Web 应用,让用户可以在标签页之外与之互动。用户可以关闭浏览器,甚至无需积极使用您的 Web 应用,即可与您的体验互动。该功能需要同时使用 Service Worker 和 Web 应用清单,并基于前面总结的一些功能。
Push API 已在 Chrome 中实现,在 Firefox 中处于开发阶段,在 Edge 中正在考虑。Safari 尚未公开表示他们打算实现此功能。
开放网络上的推送通知是 Matt Gaunt 撰写的一篇全面介绍如何设置推送的文章,您还可以在 Web 基础知识中找到“推送通知”Codelab。
如果您更喜欢观看视频,Chrome 团队的 Michael van Ouwerkerk 还提供了一个 6 分钟的简介来介绍推送功能。
叠加高级功能
请注意,用户体验的甜度可能会因查看 Web 应用所用的浏览器而异。您可以控制硬糖外壳。
您还可以通过这种方式将 Web 平台即将推出的其他功能(例如后台同步,用于在 Web 应用关闭时与服务器同步数据)和 Web Bluetooth(用于通过 Web 应用与蓝牙设备通信)叠加到您的渐进式 Web 应用中。
Chrome 已启用一次性后台同步功能,Jake Archibald 在视频中展示了其离线维基百科应用,并在文章中演示了该功能的运作方式。如果您有兴趣试用该 API,François Beaufort 还提供了一些 Web Bluetooth 示例。
支持框架
您完全可以将上述任一原则应用于您正在构建的现有应用或框架。在构建渐进式 Web 应用时,还应注意一些其他原则,例如以用户为中心的 RAIL 性能模型和基于 FLIP 的动画。
我希望在 2016 年,越来越多的样板和种子项目会将对渐进式 Web 应用的支持作为一项核心功能自然而然地融入其中。在此之前,将这些功能添加到您自己的应用的门槛并不高,而且在我看来,非常值得您付出努力。
架构
在渐进式 Web 应用模型中,您可以采用不同程度的“全包式”方法,但常见的方法是围绕应用壳进行架构设计。这不是硬性要求,但确实有诸多好处。
应用 shell 架构鼓励您缓存应用 shell(界面),以便其在离线状态下运行并使用 JavaScript 填充内容。这样一来,在用户重复访问时,即使您的内容最终来自网络,您也无需网络即可在屏幕上非常快速地获得有意义的像素。这可以显著提升性能。
Jeremy Keith 最近发表了评论,认为在这种类型的模型中,服务器端渲染可能不应被视为后备方案,而客户端渲染应被视为增强功能。这是合理的反馈。
在应用壳模型中,应尽可能使用服务器端渲染,并将客户端渐进式渲染用作增强功能,就像在支持服务工件时“增强”体验一样。最终可以通过多种方式来实现这一点。
建议您阅读我们关于该架构的文章,并评估如何将类似的原则最有效地应用于您自己的应用和堆栈。
入门模板
应用 Shell
app-shell
代码库包含 Application Shell 架构的近乎完整的实现。它的后端使用 Express.js 编写,前端使用 ES2015 编写。
由于该代码库涵盖了模型的客户端和服务器端部分,并且其中包含大量内容,因此您需要花一些时间熟悉该代码库。目前,它是我们最全面的渐进式 Web 应用起点。我们将在下一步中重点关注此项目的文档。
Polymer 入门套件
Polymer Web 应用的官方起点支持以下渐进式 Web 应用功能:
- Web 应用清单
- Android 版 Chrome 启动画面
- 使用 Platinum SW 元素实现 Service Worker 离线缓存
- 使用白金推送元素的推送通知(需要手动设置)
当前版本的 PSK 不支持您在某些渐进式 Polymer Web 应用中找到的一些更高级的性能模式(例如应用 Shell 模型、异步加载)。
我们计划在 2016 年尝试将这些模式融入 PSK,但您可以在 Rob Dodson 的 Polymer Zuperkulblog 应用和 Eric Bidelman 的精彩 Polymer 性能模式演讲中找到与此相关的早期实验。
Web 版入门套件
我们为新的基本项目提供的起点包含以下渐进式 Web 应用功能:
- Web 应用清单
- Android 版 Chrome 启动画面
- 借助 sw-precache 实现服务工件预缓存
如果您更倾向于使用原生 JS/ES2015,并且无法使用 Polymer,Web 入门套件可能非常有用,可用作参考点,供您重复使用或借鉴代码段。
使用和不使用框架的渐进式 Web 应用
社区成员已经构建了许多开源渐进式 Web 应用,其中既有使用 JS 库和框架的,也有不使用 JS 库和框架的。如果您需要灵感,以下代码库可能非常有用。这些应用也非常出色。
纯 JavaScript
- Paul Lewis 的 Voice Memos 使用与
app-shell
类似的架构构建而成(编写说明) - Jake Archibald 的 Offline Wikipedia(离线维基百科)(视频)
- 由 Paul Kinlan 创作的 Air Horner
- Paul Lewis 的吉他调音器(说明)
Polymer
- Rob Dodson 的 Zuperkulblog(幻灯片)
回应
虚拟 DOM
Angular.js
- Kenneth Auchenberg 的 Timey.in - 也使用
sw-precache
进行资源预缓存
结语
如前所述,渐进式 Web 应用仍处于起步阶段,但这是一个令人兴奋的时刻,您可以尝试使用其背后的方法,看看它们能否很好地应用于您自己的 Web 应用。
Paul Kinlan 目前正在规划有关渐进式 Web 应用的 Web 基础知识指南。如果您有关于希望涵盖哪些领域的意见,欢迎随时在会话中发表评论。