You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
9.4 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 27 | 渐进式网页应用PWA它究竟解决了Web应用的哪些问题
在专栏[开篇词](https://time.geekbang.org/column/article/113399)中,我们提到过浏览器的三大进化路线:
* 第一个是应用程序Web化
* 第二个是Web应用移动化
* 第三个是Web操作系统化
其中第二个Web应用移动化是Google梦寐以求而又一直在发力的一件事不过对于移动设备来说前有本地App后有移动小程序想要浏览器切入到移动端是相当困难的一件事因为浏览器的运行性能是低于本地App的并且Google也没有类似微信或者Facebook这种体量的用户群体。
但是要让浏览器切入到移动端让其取得和原生应用同等待遇可是Google的梦想那该怎么做呢
这就是我们本节要聊的PWA。那什么是PWAPWA又是以什么方式切入到移动端的呢
PWA全称是Progressive Web App翻译过来就是渐进式网页应用。根据字面意思它就是“渐进式+Web应用”。对于Web应用很好理解了就是目前我们普通的Web页面所以PWA所支持的首先是一个Web页面。至于“渐进式”就需要从下面两个方面来理解。
* 站在Web应用开发者来说PWA提供了一个渐进式的过渡方案让Web应用能逐步具有本地应用的能力。采取渐进式可以降低站点改造的代价使得站点逐步支持各项新技术而不是一步到位。
* 站在技术角度来说PWA技术也是一个渐进式的演化过程在技术层面会一点点演进比如逐渐提供更好的设备特性支持不断优化更加流畅的动画效果不断让页面的加载速度变得更快不断实现本地应用的特性。
从这两点可以看出来PWA采取的是非常一个缓和的渐进式策略不再像以前那样激进动不动就是取代本地App、取代小程序。与之相反而是要充分发挥Web的优势渐进式地缩短和本地应用或者小程序的距离。
那么Web最大的优势是什么呢我认为是自由开放也正是因为自由和开放所以大家就很容易对同一件事情达成共识达成共识之后一套代码就可以运行在各种设备之上了这就是跨平台这也恰恰是本地应用所不具备的。而对于小程序倒是可以实现跨平台但要让各家达成共识目前来看似乎还是非常不切实际的。
所以我给PWA的定义就是**它是一套理念渐进式增强Web的优势并通过技术手段渐进式缩短和本地应用或者小程序的距离**。基于这套理念之下的技术都可以归类到PWA。
那今天我们就主要来聊聊PWA主要采用了哪些技术手段来缩短它和本地应用或者小程序的距离。
## 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的概念它的主要思想是**在页面和网络之间增加一个拦截器,用来缓存和拦截请求**。整体结构如下图所示:
![](https://static001.geekbang.org/resource/image/23/12/23b97b087c346cdd378b26b2d158e812.png)
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。
除了必须要使用HTTPSService Worker还需要同时支持Web页面默认的安全策略诸如同源策略、内容安全策略CSP关于这些后续我们也会详细介绍。
## 总结
好了,今天就介绍到这里,下面我来总结下本文的主要内容。
我们先分析了PWA它是由很多技术组成的一个理念其核心思想是**渐进式**。对于开发者它提供了非常温和的方式让开发者将普通的站点逐步过渡到Web应用。对于技术本身而言它是渐进式演进逐渐将Web技术发挥到极致的同时也逐渐缩小和本地应用的差距。在此基础上我们又分析了PWA中的Service Worker的设计思路。
另外PWA 还提供了 manifest.json 配置文件可以让开发者自定义桌面的图标、显示名称、启动方式等信息还可以设置启动画面、页面主题颜色等信息。关于manifest.json的配置还是比较简单的详细使用教程网上有很多这里我就不做介绍了。
添加桌面标、增加离线缓存、增加消息推送等功能是PWA走向设备的必备功能但我认为真正决定PWA能否崛起的还是底层技术比如页面渲染效率、对系统设备的支持程度、WebAssembly等而这些技术也在渐进式进化过程中。所以未来如何我们拭目以待。
## 思考时间
预测未来最好的方式是理解现在那么今天我留给你的思考题是你觉得PWA能进入移动设备吗
欢迎在留言区与我分享你的想法,也欢迎你在留言区记录你的思考过程。感谢阅读,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给更多的朋友。