该用什么姿式来使用 PWA

转自IMWeb社区,做者:黎清龙,原文连接html

注:本文须要有必定的 PWA 基础前端

1. 什么是 PWA?

要知道一个东西是什么,咱们一般能够从它的名字入手webpack

所以咱们看下 PWA 的全称是: Progressive Web Appweb

回答 what 这种问题,重点在于名词,所以 PWA 是一个 APP,一个独立的、加强的、Web 实现的 APP浏览器

要达到这样的目的,PWA 提供了一系列的技术 & 标准,以下图所示:缓存

具体每一项技术是什么就再也不赘述了,感兴趣的同窗自行网上搜索! 下面有一个简单的 demo 能够简单体会一下:性能优化

之后咱们的 web 站点能够像 app 同样,这难道不是一个使人兴奋的事情吗?架构

因此 PWA 是值得咱们前端开发者一直关注的技术!并发

按照目前的兼容性和环境来看,你们应用最多的仍是 Service Worker,所以接下来咱们也是把重点放在 SW 上面app

那什么是 Service Worker ?

你们都知道就不卖关子了,其实就是一个 Cache

说到 Cache,就必定会想到性能优化了,请看咱们的第二部分

2. 首屏优化

2.1. 静态资源优化

如何利用 Cache 来进行优化?这个基本套路应该无人不知了:

那么首次加载怎么办呢?首次加载是没有缓存资源的,因此会走到线上,因此等于没有任何优化

答案就是 Cache 的第二种经常使用技巧: precache(预加载)

预加载的意思就是在某个地方或特定时机预先把须要用到的资源加载并缓存

咱们的作法以下图所示:

构建的时候,把整个项目用到的资源输出到一个 list 中,而后 inline 到 sw.js 里面

当 sw install 时,就会把这个 list 的资源所有请求并进行缓存

这样作的结果就是,不管用户第一次进入到咱们站点的哪一个页面,咱们都会把整个站点全部的资源都加载回来并缓存

当用户跳转另一个页面的时候,Cache 里面就有相应的资源了!

这是咱们辅导课堂页面接入 sw 以后的首屏优化效果:

2.2. 动态数据优化

除了静态资源以外,咱们还能缓存其余的内容吗?

答案确定是能够的,咱们还能够缓存 cgi 数据

缓存 cgi 数据的流程和缓存静态资源的流程主要有2个差异,上图标红的地方:

  1. 须要添加一个开关功能,由于不是全部 cgi 都须要缓存的!
  2. 页面须要展现最新的数据,所以在返回缓存结果以后,还须要请求线上最新的数据,更新缓存,而且返回给页面展现,也就是说页面须要展现2次

页面展现2次须要考虑页面跳动的体验问题,选择权在于业务自己!

这是咱们辅导上课页接入该功能后的首屏优化效果:

动态数据缓存是否有意义还须要额外的逻辑来判断,这块暂时是没有作的,后续会补上相关统计

2.3. 直出html优化

还能缓存什么?咱们想到了直出的 html

这里就不展开讲了,由于咱们的 jax 同窗已经分享了一篇优秀的文章《企鹅辅导课程详情页毫秒开的秘密 - PWA 直出》,能够去看看哈~

3. 替代离线包

PWA 与离线包本质上是同样的,都是离线缓存

正好,咱们 PC 客户端的离线包系统年久失修,在这个契机下,咱们启动了使用 PWA 替换离线包的方案!

核心流程不变,基本和缓存静态资源的流程是一致的

可是离线包系统是很是成熟的系统,要彻底替换掉它还须要考虑许多方面的问题。

3.1. 更新机制

离线包有个自动更新的机制,每隔一段时间就会去请求离线包管理系统是否有更新,有的话就把最新的离线包拉下来自动更新替换,这样只须要1次跳转就能展现最新的页面。

SW 没有自动更新的逻辑,它须要在页面加载(一次跳转)以后才会去请求 sw.js,判断有变化才会进行更新,更新完了要等到下一次页面跳转(二次跳转)才能展现最新的页面。

这里有两个方案:

  1. 参考离线包的更新机制,也给 SW 实现一个自动更新的逻辑,借用 update 接口是能够作到主动去执行 SW 更新的。可是很是遗憾,咱们的客户端 webkit 内核版本过低,并不支持这个接口
  2. 在第一次跳转以后更新 sw,而后检测 sw 状态,发现若是有更新,就用必定的策略来进行页面的刷新

咱们使用第2个方案,部分代码以下:

在检测到 sw 更新以后,咱们能够选择强刷,或者提示用户手动刷新页面,具体实现页面能够经过监听事件来处理

更多详细的实现方案能够参考这篇文章哈:How to Fix the Refresh Button When Using Service Workers

3.2. 首次打开问题

通常离线包是打进 app 的安装包一块儿发布的,在用户下载安装以后,离线包就已经存在于本地,所以第一次打开就能享受到离线包的缓存。

可是 sw 没有这个能力,一样咱们也有两个方案:

  1. 在 app 安装的时候,添加一步,经过建立 webview 加载页面,页面执行 SW 的初始化工做,并展现相应的进度提示,在安装完成后须要把 webview 的 SW Cache 底层文件 copy 到相应的安装位置。这个方案太复杂,衡量下来没有采用
  2. 在 app 启动时,建立一个隐藏的 webview,加载空页面去加载 SW。

咱们使用第2个方案,由于咱们的 app 启动会先让用户登陆,以下图所示:

注:这里 app 不是移动端 app,是 pc 的客户端 app

3.3. 屏蔽机制

有时候咱们不想使用离线缓存能力,好比在咱们开发的时候

在离线包系统,一般会有一个开发者选项是【屏蔽离线包】

SW 也是须要这种能力的,这个方案就比较简单了,在 sw.js 的逻辑里有一个全局的开关,当开关关闭时,就不会走缓存逻辑

所以,咱们能够在 dev 环境下把开关关闭便可达到屏蔽的做用

3.4. 降级方案

当咱们发布了一个错误代码的时候,咱们须要快速降级容错的能力

在离线包系统里面有个过时的功能,能够把某个版本设置过时,也就是废弃掉:

咱们利用以前提到的全局开关,经过一个管理接口来设置开关的起开和关闭,便可达到快速降级的目的:

整个流程大体是这样:

  1. 发布了错误代码,而且用户本地 sw 已经更新缓存了错误代码
  2. 在管理端关闭使用缓存开关,让用户走线上
  3. 快速修复代码并发布,到这里页面就已经恢复正常
  4. 在管理端开启使用缓存开关,恢复 SW 功能

请求管理接口是轮询的,这里后续有计划会改为 push,这样会更加及时,固然还要详细评估方案以后才能落实。

4. 如何方便接入?

咱们把上述功能集成到了一个 webpack 插件当中,在构建的时候就自动输出 sw.js 并把相关内容注入到 html 文件中,该插件正准备开源哈~

5. 将来

将来对于 PWA 还能作些什么?笔者觉得有如下 2 个方面

5.1. 业务深耕

目前通用的能力已经基本挖掘完成,可是 SW 由于它独特的特性,它能作的事情太多了,可是具体要不要这么作也是因业务而异,并且这些内容可能会很复杂,因此我称为业务深耕。

SW 什么特性?请看下面 2 张图就能够理解了

这种架构相信已经可以看出来了,没错,SW 有间件(层)的特性,那它能作的东西就太多了(虽然 SW 是用户端本地中间层)

简单举几个例子:

  1. server 负载控制:当发现 server 端高负载时,SW 能够丢弃请求,或者缓存请求,合并/延迟发送。
  2. 预请求:SW 能预缓存的资源是能够构建出来的资源,可是咱们还有许多资源是不能在构建阶段知道的,好比图片,第三方资源等,SW 在返回资源请求(好比HTML、cgi 数据)以后,能够扫描资源里面的内容,若是发现包含了其余资源的 url,那说明页面颇有可能待会就会请求这些资源,这时 SW 能够提早去请求这些资源;再好比翻页的数据
  3. 缓存自动更新:经过与 server 创建联系,当数据有变化时,server 直接把最新的数据 push 到 SW 进行缓存的更新

5.2. 关注 PWA

回到最开始,PWA 是一项使人兴奋的技术,可是浏览器兼容有限,所以期待并关注 PWA 技术的发展是颇有必要的!

固然,能推进就更好了!好比推进咱们的 X5 内核尽快支持新特性。

相关文章
相关标签/搜索