穿上App外衣,保持Web灵魂——PWA温故

穿上App的外衣,保持Web的灵魂—— PWA

早在2015年,设计师弗朗西斯·贝里曼和Google Chrome的工程师亚历克斯·罗素提出“PWA(渐进式网络应用程序)”概念,将网络之长与应用之长相结合,其核心目标就是提升 Web App 的性能,改善 Web App以媲美Native的流畅体验。

1. 什么是PWA

PWA 不是一个框架或工具集,而是一个概念,是开发人员需要在应用程序中实现的一组功能,以便将应用程序的用户体验提升到一个新的水平上。如果说某网站在某种程度上是 PWA,那它满足的 PWA 功能清单中的特性越多,它就越接近这个概念。

PWA是一类Web应用程序的统称,通过高级Web功能使Web应用程序的行为和表现像本地应用程序一样。PWA 可以通过一个代码库在多个平台和多个设备上运行,像一个特定平台的应用程序那样,可以安装在设备上,可以离线和在后台运行,并且可以与设备和其他已安装的应用程序集成。

PWA能够重用现有代码以提供服务体验。基于其他的跨平台技术,往往需要一次性将适配于各种设备和平台的应用程序部署到所有商店,PWA与之有极大的不同,本质上是提供类似于原生应用程序的用户体验的网站。PWA受欢迎的原因之一是它能够满足所有面向移动网络的设备需求,同时节省了应用创建和维护的投资成本。

简单而言,一个 PWA 应用首先是一个网页, 是通过 Web 技术编写出的一个网页应用,随后通过App Shell 架构添加上 Manifest 实现添加至设备主屏幕, 在通过 Service Worker 来实现离线缓存和消息推送等功能。

2.PWA 的关键技术

归纳而言,PWA 应用中有两项关键技术:基于Manifest的App Shell 架构和Service worker运行机制。

2.1 基于Manifest的App Shell架构

App Shell 架构是构建 PWA 应用的一种方式,能即时可靠且地将PWA加载到用户屏幕上,从而与本机应用相似。

作为一种PWA的构建方式,App Shell架构提供了一个最基本的 Web App 框架,包括应用的头部、底部、菜单栏等结构。App Shell 架构通常使用JavaScript框架(如React或Angular)来实现,可以是一种构建单页面应用(SPA)的方法,它将逻辑与实际内容分离开来。

App Shell 架构涉及缓存静态资源,然后使用JavaScript动态加载实际内容,是一个能够支持用最小化HTML/CSS/JS用户界面集合的可缓存UI框架。如果有离线缓存,可确保在用户重复访问时提供即时、可靠的良好性能。这样一来,用户重复打开应用时就能迅速地看到 Web App 的基本界面,只需要从网络中请求、加载必要的内容。这也意味着并不是每次用户访问时都要从网络加载 App Shell,而只需要从网络中加载必要的内容。 

 App Shell 是通过浏览器中的Web runtime 完成的web 应用与当前设备平台的交互,尤其是在当前设备的屏幕上增加应用的启动入口。

Web Application Manifest,即通过一个清单文件向浏览器暴露 web 应用的元数据,包括名称、icon 的 URL 等,以备浏览器使用,比如在添加至主屏或推送通知时暴露给操作系统,从而增强 web 应用与操作系统的集成能力。Manifest就是一个json文件,一个简单示例如下:

代码语言:javascript
复制
{
"name": "Progressive web app sample",
"short_name": "pwa sample",
"start_url": "/index.html",
"display": "standalone",
"theme_color": "#FFDF01",
"background_color": "#FFDF01",
"icons": [
{
"src": "homescreen.png",
"sizes": "168x168",
"type": "image/png"
},
{
"src": "homescreen-124.png",
"sizes": "124x124",
"type": "image/png"
}
]
}

当用户第一次访问PWA应用程序时,浏览器会按照manifest.json文件的内容对应用程序进行注册与安装,以便随时在离线状态下访问。

对于使用包含大量 JavaScript 的架构的单页面应用来说,基于Manifest 的 App Shell 适用于在没有网络的情况下将一些初始 HTML 快速加载到屏幕上。

2.2 Service worker

Service worker是 web技术中worker 的一种,那么,什么是worker呢?

由于Javascript 的单线程特性,任何“重量”操作都会阻塞主线程。为了提升性能和体验,现代浏览器使用worker 作为一种多线程机制,把原本的单线程应用变成多线程运行。现代浏览器中提供了 3 种 Worker,分别是:

  • Web worker—— 包含专用 worker及共享 worker
  • Service worker
  • Worklet—— 包含PaintWorklet、AudioWorklet、AnimationWorklet、LayoutWorklet。其中,Worklet 与硬件交互设计相关且仍处于试验状态。Web worker 特别适用于后台跑脚本。现在的网页都可以注册多个 Worker,让不同的任务在各自独立的环境中完成。Service worker 相当于是浏览器在网页和服务器通信中插入的一个“中间层”,本质上充当代理,以编程方式拦截和处理来自页面的网络请求,甚至可以从各种来源产生全新的反应并构建HTML。

关于service worker 的主要内容,下图给出了核心提示:

在Service Worker安装期间预加载文件。对于SPA,这通常包括我们之前讨论的“应用程序外壳”,而简单的静态网站可能会选择预加载所有HTML、CSS和JavaScript,以确保离线时基本功能得到维护。处理推送通知,类似于本机应用程序。这意味着网站可以获得用户的许可来发送通知,然后依靠Service Workers接收消息并执行消息,即使浏览器关闭。 .

2.3 基于Service worker 的Push、notification 和后台服务

目前,不同的浏览器厂商使用了不同的Push Service,chrome使用了自家的FCM,firefox也是使用自家的服务,不同push服务遵循共同的Web Push协议,具有标准的调用方式。

其中,“UA”就是我们的用户客户端,也就是浏览器;“Application Server”是后端服务;“Push Service”作为中间代理商,扮演着核心角色。Push Service接收客户端的消息订阅,维护管理“客户端url-公钥”对的列表,并将订阅和私钥信息发送给服务器进行存储;此外,它后续还得接收服务端的推送消息,校验并发送给对象的客户端进行展示。

Push Service还有一个非常重要的功能:当用户离线时,可以帮我们保存消息队列,直到用户联网后再发送给他们。

Notification通知的功能与消息push类似,但更为简单,只要设置好通知消息,调用service worker的相同通知接口即可,甚至可以可以带操作,

后台同步也是Service Worker的一个子功能,用于在终端弱网或无王情况下同步后台的数据或继续前端的请求消息 由于service worker在浏览器关闭后仍然运行着,所以即使用户没有网络或关闭客户端,service worker仍会存储相应的请求,并在有可用网络连接时发起数据同步。

3. PWA 的应用特性与功能特点

Google 给出的 PWA 应用特性如下:

  • 可靠:即使在互联网连接不佳或没有互联网的情况下,也可以快速加载。当没有互联网连接时,PWA 会使用 Service Worker 来消除对Web服务器的依赖。
  • 快速:流畅的动画和交互效果,应用程序拥有原生的体验,没有笨拙的网页滚动。
  • 参与感:能够全屏运行(如果添加到手机桌面),并处理通知。

PWA 应用主要功能特点如下:

  • 渐进增强:在尽可能多的环境中运行,可以使用任何可用的服务,并在没有服务的情况下优雅地降级。
  • 响应式用户界面:该应用程序适应各种输入方式(触摸、语音等)和输出方式(不同的屏幕尺寸、振动、音频、盲文显示等)。
  • 连接独立性:该应用程序在离线状态下以及间歇性或低带宽网络连接下也能运行良好。
  • App-like UI:应用程序采用原生平台的 UI 元素,能够快速加载的用户界面。
  • 持续更新:Service Worker API 定义了一个将应用程序自动更新到新版本的过程。
  • 安全通信:通过 HTTPS 提供服务和通信,以防止窥探和攻击。
  • 应用程序发现:即SEO友好,W3C 网络应用程序清单等元数据,使搜索引擎能够找到网络应用程序。
  • 推送交互:推送通知等功能可以主动让用户了解最新信息。
  • 后台加载:网页关闭,PWA 仍然可以在后台运行获取数据更新(当然有限制)。
  • 本机可安装性:可以安装 Web 应用程序,无需通过本机应用程序商店来进行。
  • 可链接性:通过 URL 轻松共享应用程序,无需显示安装即可运行。
  • 可再次访问,通过 URL 可以轻松分享应用,不用复杂的安装即可运行。
  • 轻量级:web应用更加轻量级,整个APP都在KB占用内。

2.4 PWA开发工具与生态影响

渐进式web应用程序(PWA)框架简单可靠,开发人员可以使用不同的来开发PWA,常见的开发工具框架如下:

  • VueJS:Vue是顶级的PWA框架库之一,因为它简化了编码并提供了高速渲染。
  • AngularJS:2009年由谷歌发布,是PWA应用程序开发中最广泛的流程之一。
  • ReactJS:2013年由Facebook发布的React包含了一个广泛的JavaScript库,使用JSX呈现连接HTML结构的函数来提供React PWA解决方案。
  • Ionic:一个开源SDK,提供了一个庞大的插件库,能够在无需编码的情况下访问API
  • Polymer:Polymer具有多种工具、组件和模板,使用纯HTML、CSS或JavaScript的一个独立框架
  • Magento PWA Studio:提供创建、部署和管理PWA所需的一切,包括用于构建用户界面、管理数据和测试应用程序的工具。
  • Svelte:一个用于开发PWA的JavaScript框架,构建了快速加载的小代码包。

对于软件生态而言,PWA确实对一些传统的应用软件和开发方式带来了一定的冲击和改变。

对于一些开发商而言,PWA技术的出现意味着需要考虑在Web端进行应用开发,并为用户提供更好的Web应用体验。但同时,PWA的开发方式也使得他们可以更加灵活地进行应用开发,并且减少了一些原生应用的开发和发布成本。

PWA技术的出现可能会对应用商店造成一定的冲击,因为PWA可以通过浏览器直接访问,不需要下载和安装,这可能会导致一些应用商店用户流失。但是,应用商店也可以通过采取措施,例如推出PWA应用、提供更好的应用变现机会等来应对这种变化。

对于用户而言,PWA技术的出现可能会提供更好的Web应用体验,例如离线访问、桌面快捷方式、推送通知等功能,同时也可以减少一些应用的下载和安装成本。但是,用户也需要考虑PWA应用在一些方面可能相对于原生应用和小程序存在的较多局限性和不足。

PWA技术对于应用软件开发商、应用商店和用户都可能会产生一定的影响,但是它并不会完全颠覆原有的开发和使用方式。PWA的优点和缺点都是相对的,不同的应用场景和开发需求会影响开发者对PWA和原生应用的选择。如果应用的功能、性能和用户体验要求较高,可以考虑原生应用;如果希望对开发和维护成本进一步降低,但又拥有app的一些特征,可以考虑使用PWA。

2.5 PWA 与小程序

各种类型的小程序都或多或少地继承或借鉴了PWA的技术理念,可以认为PWA是各种小程序的源头之一。

依托于超级App,微信、百度、支付宝等公司都推出了各自的小程序。归纳而言,小程序采用了轻量级的框架和组件,加载速度快,用户可以迅速打开应用程序。小程序能够与设备的硬件功能(如摄像头、定位、陀螺仪等)进行原生集成,提供更丰富的功能和用户体验。通过应用商店进行分发,用户可以方便地搜索、发现和安装小程序。小程序开发使用统一的开发工具和语言,在一定程度上减少了开发者的学习成本。另外小程序可以共享用户数据,提供更便捷的登录和数据传输。

PWA可以在几乎所有现代浏览器上运行,具有广泛的设备和平台支持。开发者可以充分利用现有的Web开发知识和工具,庞大的开发者社区来提供丰富的资源、工具和支持。小程序可以通过超级App作为流量入口,也可以运行在企业自有App中,任何企业的App只需要通过集成小程序运行时SDK,即可获得小程序运行能力,让小程序拥有了更多分发渠道。小程序生态系统提供了数据分析和统计工具,帮助开发者了解用户行为、应用性能和使用情况。开发者可以通过这些工具获取关键指标和数据,进行数据驱动的优化和改进。这些工具提供了可视化的报表和图表,帮助开发者更好地理解用户行为和应用运行情况。

PWA和小程序都是当前移动应用开发领域的热门技术方案,各具特色。从开发者的角度来看,PWA具有广泛的浏览器支持、跨平台能力和成熟的Web开发生态系统。小程序则在流量入口、应用商店支持和与硬件集成方面表现突出。

2.6 小结

PWA 是一种先进的理念和技术探索,但理念并不能直接演变成竞争优势。现在是2023年了,推广和应用成本更低的PWA仍然活在小程序阴影下,看起来仍然没法撼动应用开发的现状。除了国内各平台的强势影响力和平台审核因素外,PWA仍然存在一些明显缺点。PWA是一个基于浏览器的web端技术,相较于native APP的各项系统级功能明显不足,比如无法做硬件层面的调用;在动画、渲染等方面性能也明显弱于native APP;大计算量处理和音视频方面也都是弱项。

那么,如果PWA 要获得更加广泛的应用,优先级最高的突破点在哪里呢?

【参考资料与关联阅读】

  • Dean Hume,Manning,“Progressive Web Apps”
  • https://web.dev/blog
  • https://segmentfault.com/a/1190000041729491
  • https://developer.mozilla.org/zh-CN/docs/Web/Progressivewebapps
  • https://zhuanlan.zhihu.com/p/598814908
  • https://blog.51cto.com/u_15147537/5631116
  • https://blog.bitsrc.io/what-is-a-pwa-and-why-should-you-care-388afb6c0bad
  • https://infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul/
  • http://blueskyawen.com/2019/02/15/PWA-and-service-worker-in-angular/
  • https://developers.google.com/web/progressive-web-apps/
  • https://www.w3.org/TR/push-api/
  • https://w3c.github.io/manifest/
  • https://html.spec.whatwg.org/multipage/#dom-worker
  • https://www.w3.org/TR/service-workers/
  • WebAssembly的一知半解
  • web系统中的结构化数据标记
  • Web3.0,区块链后花园的姹紫嫣红
  • 基于P2P的互联网内容加速
  • 面向互联网应用的网络优化
  • 网络应用程序的通信视角
  • 与代码无关的网络安全
  • 计算机网络的元认知、实践与未来