渐进式网页应用(Progressive Web Apps,PWA)

读者来稿 · admin与 batype 的 AI 分身对话整理

·2466 字 · 约 7 分钟

**渐进式网页应用(Progressive Web Apps,PWA)**是一种使用现代Web技术构建的应用,它能够提供类似于原生应用体验的网页应用。PWA核心的理念是渐进性增强,即在基本的网页功能基础上逐步添加现代Web特性,使得网页应用能在任何设备和任何浏览器上运行,并且在网络环境较差或者离线状态下仍可使用。

PWA通常具备以下特点:

  1. 响应式设计: PWA网页设计上通常是响应式的,意味着它们能够适配各种屏幕尺寸和设备。

  2. 离线工作: 使用Service Workers,PWA能够在没有网络连接的情况下工作,提供核心内容和功能。

  3. 类似应用的交互: PWA在交互上更近似于原生应用,包括滑动手势、平滑的动画和无需页面刷新的导航体验。

  4. 安全性: PWA通常通过HTTPS协议提供服务,确保数据传输的安全性。

  5. 易于发现: 由于PWA本质上是网站,它们能够被搜索引擎检索到,比原生应用更容易被用户发现。

  6. 可安装: 用户可以将PWA添加到手机主屏幕,不需要通过应用商店进行下载。

  7. 自动更新: PWA可以自动更新,用户无需手动更新应用。

  8. 推送通知: PWA可以使用Web推送技术发送推送通知,提高用户参与度。

  9. 链接可共享: PWA的页面可以使用普通网址进行分享,用户之间分享链接时可直接访问应用的特定内容。

技术要点: 以下是构建PWA时通常需要的一些关键技术和特性:

  • Service Workers:一种运行在Web应用后台的脚本,能够拦截和缓存网络请求,提供离线访问能力。
  • Web App Manifest:一个JSON文件,描述了网页应用的名称、图标、起始URL、背景色等元数据,使得PWA可被添加到主屏幕。
  • 应用壳(App Shell)模型:设计PWA时的一种方式,目的是快速加载应用的核心UI框架,然后动态加载内容。
  • 推送通知API:允许应用接收和显示系统级的推送通知。

Web应用 VS 本地应用#

那相对于本地应用,Web页面到底缺少了什么?

  • 首先,Web应用缺少离线使用能力,在离线或者在弱网环境下基本上是无法使用的。而用户需要的是沉浸式的体验,在离线或者弱网环境下能够流畅地使用是用户对一个应用的基本要求。
  • 其次,Web应用还缺少了消息推送的能力,因为作为一个App厂商,需要有将消息送达到应用的能力。
  • 最后,Web应用缺少一级入口,也就是将Web应用安装到桌面,在需要的时候直接从桌面打开Web应用,而不是每次都需要通过浏览器来打开。 针对以上Web缺陷,PWA提出了两种解决方案:通过引入Service Worker来试着解决离线存储和消息推送的问题,通过引入manifest.json来解决一级入口的问题。下面我们就来详细分析下Service Worker是如何工作的。

什么是Service Worker#

我们先来看看 Service Worker是怎么解决离线存储和消息推送的问题。

其实在Service Worker之前,WHATWG小组就推出过用App Cache标准来缓存页面,不过在使用过程中App Cache所暴露的问题比较多,遭到多方吐槽,所以这个标准最终也只能被废弃了,可见一个成功的标准是需要经历实践考量的。

所以在2014年的时候,标准委员会就提出了Service Worker的概念,它的主要思想是在页面和网络之间增加一个拦截器,用来缓存和拦截请求。整体结构如下图所示:

Service Worker结构示意图

在没有安装Service Worker之前,WebApp都是直接通过网络模块来请求资源的。安装了Service Worker模块之后,WebApp请求资源时,会先通过Service Worker,让它判断是返回Service Worker 缓存的资源还是重新去网络请求资源。一切的控制权都交由Service Worker来处理。

Service Worker的设计思路#

现在我们知道Service Worker的主要功能就是拦截请求和缓存资源,接下来我们就从Web应用的需求角度来看看Service Worker的设计思路。

1. 架构#

通过前面页面循环系统的分析,我们已经知道了JavaScript和页面渲染流水线的任务都是在页面主线程上执行的,如果一段JavaScript执行时间过久,那么就会阻塞主线程,使得渲染一帧的时间变长,从而让用户产生卡顿的感觉,这对用户来说体验是非常不好的。

为了避免JavaScript过多占用页面主线程时长的情况,浏览器实现了Web Worker的功能。Web Worker的目的是让JavaScript能够运行在页面主线程之外,不过由于Web Worker中是没有当前页面的DOM环境的,所以在Web Worker中只能执行一些和DOM无关的JavaScript脚本,并通过postMessage方法将执行的结果返回给主线程。所以说在Chrome中, Web Worker其实就是在渲染进程中开启的一个新线程,它的生命周期是和页面关联的。

“让其运行在主线程之外”就是Service Worker来自Web Worker的一个核心思想。不过Web Worker是临时的,每次JavaScript脚本执行完成之后都会退出,执行结果也不能保存下来,如果下次还有同样的操作,就还得重新来一遍。所以Service Worker需要在Web Worker的基础之上加上储存功能。

另外,由于Service Worker还需要会为多个页面提供服务,所以还不能把Service Worker和单个页面绑定起来。在目前的Chrome架构中,Service Worker是运行在浏览器进程中的,因为浏览器进程生命周期是最长的,所以在浏览器的生命周期内,能够为所有的页面提供服务。

2. 消息推送#

消息推送也是基于Service Worker来实现的。因为消息推送时,浏览器页面也许并没有启动,这时就需要Service Worker来接收服务器推送的消息,并将消息通过一定方式展示给用户。关于消息推送的细节这里我们就不详述了,如果你感兴趣的话可以自行搜索相关资料去学习。

3. 安全#

基于Web应用的业务越来越多了,其安全问题是不可忽视的,所以在设计Service Worker之初,安全问题就被提上了日程。

关于安全,其中最为核心的一条就是HTTP。我们知道,HTTP采用的是明文传输信息,存在被窃听、被篡改和被劫持的风险,在项目中使用HTTP来传输数据无疑是“裸奔”。所以在设计之初,就考虑对Service Worker采用HTTPS协议,因为采用HTTPS 的通信数据都是经过加密的,即便拦截了数据,也无法破解数据内容,而且HTTPS还有校验机制,通信双方很容易知道数据是否被篡改。关于HTTPS协议,我们会在最后的安全模块详细介绍。

所以要使站点支持Service Worker,首先必要的一步就是要将站点升级到HTTPS。

除了必须要使用HTTPS,Service Worker还需要同时支持Web页面默认的安全策略,诸如同源策略、内容安全策略(CSP)等,关于这些,后续我们也会详细介绍。

总结#

好了,今天就介绍到这里,下面我来总结下本文的主要内容。

我们先分析了PWA,它是由很多技术组成的一个理念,其核心思想是渐进式。对于开发者,它提供了非常温和的方式,让开发者将普通的站点逐步过渡到Web应用。对于技术本身而言,它是渐进式演进,逐渐将Web技术发挥到极致的同时,也逐渐缩小和本地应用的差距。在此基础上,我们又分析了PWA中的Service Worker的设计思路。

另外,PWA 还提供了 manifest.json 配置文件,可以让开发者自定义桌面的图标、显示名称、启动方式等信息,还可以设置启动画面、页面主题颜色等信息。关于manifest.json的配置还是比较简单的,详细使用教程网上有很多,这里我就不做介绍了。

添加桌面标、增加离线缓存、增加消息推送等功能是PWA走向设备的必备功能,但我认为真正决定PWA能否崛起的还是底层技术,比如页面渲染效率、对系统设备的支持程度、WebAssembly等,而这些技术也在渐进式进化过程中。所以未来如何,我们拭目以待。

总之,PWA是将传统网页与原生应用体验结合的开发模式,它利用了Web平台的许多优势,为用户带来更好的体验,同时简化了开发者的发布和维护工作。随着Web技术的不断发展,PWA的功能和性能正在逐渐接近原生应用。