渐进式网络应用程序

<image>

渐进式网页应用程序（PWA，亦作progressive web app）是一种网页应用程序，可以作为独立的应用程序安装于装置上。PWA是透过装置的网页浏览器之离线快取机制进行安装的。

PWA自2016年起被提出，作为原生（针对特定装置开发）应用程序的替代方案，其优势在于无需为不同平台分别打包或发布。它们可在多种系统上使用，包括台式电脑与移动设备。是否将其发布至数位发行平台（例如Apple App Store、Google Play或Windows的Microsoft Store）属于使用者的选择。

由于PWA以网页或网站形式呈现，并使用常见之网页技术建构，包括HTML、CSS、JavaScript及WebAssembly，因此它可以在任何支援 PWA 的浏览器之平台上运作。至2021年止，PWA的功能已被若干主流浏览器不同程度地支援，包括Google Chrome、Apple Safari、Brave、Firefox for Android与Microsoft Edge，但尚未被Firefox桌面版支援。

## 历史

### 前身

在2007年的Apple全球开发者大会上，Steve Jobs宣布iPhone将“运行以Web 2.0互联网标准所建立的应用程序”。此架构无需软件开发套件（SDK），应用程序将透过Safari浏览器引擎完整整合于装置之中。然而，该模式后来转向透过App Store发布，以安抚感到受限的开发者社群。Jobs于2007年10月宣布，隔年将推出SDK。因此，虽然Apple持续支援网页应用程序，但绝大多数iOS应用程序最终仍转向App Store架构。

自2010年代初期起，动态网页允许开发者使用网页技术建立互动式的网页应用程序。响应式网页设计及其提供的弹性萤幕尺寸，使 PWA 开发变得更为可行。同时HTML、CSS及JavaScript的持续强化，让网页应用程序得以具备更高程度的互动性，进而实现类似原生应用程序的体验。

2013年，Mozilla发布了Firefox OS。该系统旨在成为一款开源的操作系统，可让网页应用程序以原生应用形式在移动设备上执行。Firefox OS以Gecko排版引擎为基础，并配备使用HTML5撰写的Gaia使用者界面。Firefox OS的开发于2016年结束，并于2017年完全终止，但其分支版本仍被用作KaiOS的基础，该系统是一种功能型手机平台。

### 初始引进

在2015年，设计师Frances Berriman与Google Chrome工程师Alex Russell创造了“渐进式网页应用程序”（Progressive Web Apps，简称 PWA）这个词汇，用以描述利用现代浏览器所支援的新功能（包含和网页应用程序清单）的应用，让使用者能够将网页应用程序升级为在原生操作系统中运行的渐进式网页应用程序。接着，Google对Android平台的PWA开发投入大量推广工作。Firefox于2016年开始支援服务工作者，而Microsoft Edge与Apple Safari则于2018年跟进，使服务工作者可以在所有主要系统上工作。

到了2019年，部分浏览器的桌面版本开始支援PWA，包括Microsoft Edge（在Windows）以及Google Chrome（在Windows、macOS、ChromeOS及Linux上）。

在2020年12月，Firefox桌面版放弃了PWA的实作（特别是移除了作为实验性功能存在的“site-specific browser”原型设定）。一名Firefox架构师指出：“我希望我们传达的讯号是，PWA支援短期内不会来到桌面版Firefox。” Mozilla 仍支援 Android 平台的 PWA，并计划继续支持。

## 浏览器支援统整表格

浏览器｜支援情况｜备注

Windows｜macOS｜Linux｜Android｜iOS & iPadOS

基于 Chromium 的浏览器｜是｜是｜是｜是｜不适用｜包含Google Chrome、Microsoft Edge、Brave、Opera、Vivaldi，以及其他基于Chromium的浏览器。

Firefox｜否 ｜否 ｜否 ｜部分｜否

Safari｜不适用｜部分 ｜不适用｜不适用｜部分

## 特色

渐进式网页应用程序（PWA）都设计成能在任何符合适当网页标准的浏览器上运作。与其他跨平台解决方案相同，目标是帮助开发者比起建立原生应用程序更轻松地建立跨平台应用程序。渐进式网页应用程序采用渐进式增强的网页开发策略。

有些渐进式网页应用程序采用一种称为应用壳模型（App Shell Model）的架构方法。在此模型中，开发者会将响应式网页设计应用程序的基本使用者界面或称“壳层”存放在浏览器的离线快取中。此模型允许PWA在有无网络连线时皆维持类似原生应用的使用体验。这可透过提供一个“初始静态框架”（initial static frame，一种能够让内容逐步以及动态地载入的架构）来加快载入的速度。

### 技术标准

Russell 在2016年描述了网站要被视为渐进式网页应用程序（并可被浏览器安装）所需的技术基准条件，并随后持续更新：

- 起源必须为安全来源。必须透过TLS服务且没有混合内容。PWA必须使用HTTPS以确保用户隐私、安全性与内容真实性。
- 必须注册一个带有 fetch 处理器的服务工作者。PWA必须利用服务工作者建立可程式化的内容快取。不同于一般HTTP web cache（在首次使用后快取内容，并用各种启发式方法判断内容何时不再需要），可程式化快取能在内容首次使用“之前”明确地预取内容，且在不再需要时明确丢弃。这有助于页面在离线或低品质网络状态下仍可使用。
- 必须参考网页应用程序 清单。清单至少要包含五个关键属性：`name` 或 `short_name`、`start_url`、`display`（值为 `standalone`、`fullscreen` 或 `minimal-ui`）、以及 `icons`（包含192 px与512 px两种尺寸版本）。清单中的资讯使 PWA 可透过 URL 轻松分享、可被搜索引擎发现，并简化复杂的安装程序（但 PWA 仍可能被列在第三方应用商店中）。此外，PWA 支援类原生应用的互动和导航，包括可加入主画面、显示启动画面等功能。

## 技术

建立渐进式网页应用程序常用许多技术。若一个网页应用符合安装标准，能离线运作并能被加入装置主画面，即可视为 PWA。要符合这些定义，所有 PWA 最少需要有清单(manifest)与服务工作者(service worker)。其他技术则用来储存资料、与服务器通讯或执行程式码。

### Manifest

网页应用程序清单（web app manifest）是由 万维网联盟（W3C）制定的一项规范，定义了一种基于 JSON 的清单格式（通常标示为 manifest.json），供服务工作者（Service worker）将与网页应用程序相关的 元资料 集中管理，包含：

- 网页应用程序的名称
- 网页应用程序图示或图片物件的连结
- 启动或开启网页应用程序的首选 URL
- 网页应用程序的设定资料
- 网页应用程序的预设画面方向
- 设定显示模式的选项，例如全萤幕

这些元资料对于应用程序能够加入主画面或被列为与原生应用程序并列的项目至关重要。

#### iOS 支援

iOS Safari 浏览器对 manifest 不完全支援，但大部分的 PWA 元资料可以透过苹果专用的 meta 标签扩充定义。这些标签允许开发者启用全萤幕显示、定义图示与启动画面（splash screen）、并指定应用程序名称。

### Service workers

服务工作者（service worker）是一种 web worker，实作了一个可程式化的网络代理，可以回应主文件发出的网络／HTTP 请求。它能够检查远端服务器的可用性，在服务器可用时快取内容，并于后续提供给文件使用。服务工作者与主文件执行绪分离运作。服务工作者可处理 推播通知、背景资料同步、快取或取回资源请求、拦截网络请求，并且能在注册它们的文件尚未载入时独立接收集中更新。

服务工作者经历三个阶段的生命周期：注册（Registration）、安装（Installation）与启用（Activation）。注册是告诉浏览器服务工作者的位置，为安装做准备。安装发生在浏览器尚无此服务工作者，或发现服务工作者有更新时。启用发生在 PWA 的所有页面都关闭后，以避免旧版本与新版本冲突。此生命周期设计也有助于保持版本切换的一致性，因为同一网域同时只能有一个活动中的服务工作者。

### WebAssembly

WebAssembly 允许 预编译 的程式码在浏览器中以近乎原生的速度执行。因此，像是 C 这类语言写成的函式库可以被加入网页应用程序中。WebAssembly 于 2015 年宣布，2017 年 3 月首次释出，并于 2019 年 12 月 5 日成为 W3C 推荐标准（W3C Recommendation）。并于 2021 年获得 程式语言软件奖（Programming Languages Software Award），该奖项由 美国计算机协会（ACM）SIGPLAN 颁发。

### 资料储存

渐进式网页应用程序（Progressive Web App，PWA）的执行环境可能会在某些情况下被卸载，因此 PWA 需要以以下其中一种方式来储存大部分的长期内部状态（使用者资料、动态载入的应用资源）：

网页储存 (Web Storage)：Web Storage 是 W3C 的标准 API，允许在现代浏览器中进行键值储存。此 API 包含两个物件，sessionStorage（提供只在会话期间有效，浏览器会话结束时清除的储存空间）和 localStorage（提供跨会话持久储存空间）。

索引数据库 API (Indexed Database API)：Indexed Database API 是一个 W3C 标准的数据库 API，在所有主要浏览器中都可使用。此 API 受现代浏览器支援，能够储存 JSON 物件及任何可表示为字串的结构。Indexed Database API 也可以搭配封装库（wrapper library）使用，以提供更多结构化功能。

## 与原生应用程序的比较

2017 年，Twitter 推出 Twitter Lite，一款作为官方原生 Android 和 iOS 应用程序的 PWA 替代方案。根据 Twitter 表示，Twitter Lite 的大小仅占原生应用程序的 1–3%。Starbucks 提供的 PWA 比其 iOS 应用程序小了 99.84%。部署 PWA 后，Starbucks 在线订单数量增加了一倍，桌面使用者的订单率约与手机应用程序使用者相同。

2018 年由 Forbes 发表的评论发现，Pinterest 的 PWA 使用者在网站上的停留时间比之前的行动网站多了 40%。广告收益率也提升了 44%，核心互动量增加了 60%。Flipkart 发现有 60% 卸载原生应用程序的用户会回来使用 Flipkart PWA。Lancôme 的 PWA 让页面可互动的时间缩短了 84%，转换率提升了 17%，iOS 移动设备上的浏览量增加了 53%。

## 透过应用程序商店发布

由于 PWA 不需要针对不同平台分别打包或发布，且使用者可以透过网页直接取得，因此开发者不需要透过像 Apple App Store、Google Play、Microsoft Store 或 Samsung Galaxy Store 等数位发行平台来发布。主要的应用商店对于 PWA 的支援程度各有不同。Google Play、Microsoft Store、和 Samsung Galaxy Store 支援 PWA，但 Apple App Store 不支援。Microsoft Store 会自动（甚至未经应用程序作者申请）发布部分符合条件的 PWA，这是透过 Bing 索引所发现的结果。

## 参见

- Google Lighthouse，Google 开发的开源 PWA 程式码审查工具
- 超级应用程序
- 微信小程序

## 外部链接

- Web Applications Working Group 标准索引