转自IMWeb社区,做者:黎清龙,原文连接html
注:本文须要有必定的 PWA 基础前端
要知道一个东西是什么,咱们一般能够从它的名字入手webpack
所以咱们看下 PWA 的全称是: Progressive Web Appweb
回答 what 这种问题,重点在于名词,所以 PWA 是一个 APP,一个独立的、加强的、Web 实现的 APP浏览器
要达到这样的目的,PWA 提供了一系列的技术 & 标准,以下图所示:缓存
具体每一项技术是什么就再也不赘述了,感兴趣的同窗自行网上搜索! 下面有一个简单的 demo 能够简单体会一下:性能优化
之后咱们的 web 站点能够像 app 同样,这难道不是一个使人兴奋的事情吗?架构
因此 PWA 是值得咱们前端开发者一直关注的技术!并发
按照目前的兼容性和环境来看,你们应用最多的仍是 Service Worker,所以接下来咱们也是把重点放在 SW 上面app
那什么是 Service Worker ?
你们都知道就不卖关子了,其实就是一个 Cache
说到 Cache,就必定会想到性能优化了,请看咱们的第二部分
如何利用 Cache 来进行优化?这个基本套路应该无人不知了:
那么首次加载怎么办呢?首次加载是没有缓存资源的,因此会走到线上,因此等于没有任何优化
答案就是 Cache 的第二种经常使用技巧: precache(预加载)
预加载的意思就是在某个地方或特定时机预先把须要用到的资源加载并缓存
咱们的作法以下图所示:
构建的时候,把整个项目用到的资源输出到一个 list 中,而后 inline 到 sw.js 里面
当 sw install 时,就会把这个 list 的资源所有请求并进行缓存
这样作的结果就是,不管用户第一次进入到咱们站点的哪一个页面,咱们都会把整个站点全部的资源都加载回来并缓存
当用户跳转另一个页面的时候,Cache 里面就有相应的资源了!
这是咱们辅导课堂页面接入 sw 以后的首屏优化效果:
除了静态资源以外,咱们还能缓存其余的内容吗?
答案确定是能够的,咱们还能够缓存 cgi 数据!
缓存 cgi 数据的流程和缓存静态资源的流程主要有2个差异,上图标红的地方:
页面展现2次须要考虑页面跳动的体验问题,选择权在于业务自己!
这是咱们辅导上课页接入该功能后的首屏优化效果:
动态数据缓存是否有意义还须要额外的逻辑来判断,这块暂时是没有作的,后续会补上相关统计
还能缓存什么?咱们想到了直出的 html
这里就不展开讲了,由于咱们的 jax 同窗已经分享了一篇优秀的文章《企鹅辅导课程详情页毫秒开的秘密 - PWA 直出》,能够去看看哈~
PWA 与离线包本质上是同样的,都是离线缓存
正好,咱们 PC 客户端的离线包系统年久失修,在这个契机下,咱们启动了使用 PWA 替换离线包的方案!
核心流程不变,基本和缓存静态资源的流程是一致的
可是离线包系统是很是成熟的系统,要彻底替换掉它还须要考虑许多方面的问题。
离线包有个自动更新的机制,每隔一段时间就会去请求离线包管理系统是否有更新,有的话就把最新的离线包拉下来自动更新替换,这样只须要1次跳转就能展现最新的页面。
SW 没有自动更新的逻辑,它须要在页面加载(一次跳转)以后才会去请求 sw.js,判断有变化才会进行更新,更新完了要等到下一次页面跳转(二次跳转)才能展现最新的页面。
这里有两个方案:
咱们使用第2个方案,部分代码以下:
在检测到 sw 更新以后,咱们能够选择强刷,或者提示用户手动刷新页面,具体实现页面能够经过监听事件来处理
更多详细的实现方案能够参考这篇文章哈:How to Fix the Refresh Button When Using Service Workers
通常离线包是打进 app 的安装包一块儿发布的,在用户下载安装以后,离线包就已经存在于本地,所以第一次打开就能享受到离线包的缓存。
可是 sw 没有这个能力,一样咱们也有两个方案:
咱们使用第2个方案,由于咱们的 app 启动会先让用户登陆,以下图所示:
注:这里 app 不是移动端 app,是 pc 的客户端 app
有时候咱们不想使用离线缓存能力,好比在咱们开发的时候
在离线包系统,一般会有一个开发者选项是【屏蔽离线包】
SW 也是须要这种能力的,这个方案就比较简单了,在 sw.js 的逻辑里有一个全局的开关,当开关关闭时,就不会走缓存逻辑
所以,咱们能够在 dev 环境下把开关关闭便可达到屏蔽的做用
当咱们发布了一个错误代码的时候,咱们须要快速降级容错的能力
在离线包系统里面有个过时的功能,能够把某个版本设置过时,也就是废弃掉:
咱们利用以前提到的全局开关,经过一个管理接口来设置开关的起开和关闭,便可达到快速降级的目的:
整个流程大体是这样:
请求管理接口是轮询的,这里后续有计划会改为 push,这样会更加及时,固然还要详细评估方案以后才能落实。
咱们把上述功能集成到了一个 webpack 插件当中,在构建的时候就自动输出 sw.js 并把相关内容注入到 html 文件中,该插件正准备开源哈~
将来对于 PWA 还能作些什么?笔者觉得有如下 2 个方面
目前通用的能力已经基本挖掘完成,可是 SW 由于它独特的特性,它能作的事情太多了,可是具体要不要这么作也是因业务而异,并且这些内容可能会很复杂,因此我称为业务深耕。
SW 什么特性?请看下面 2 张图就能够理解了
这种架构相信已经可以看出来了,没错,SW 有间件(层)的特性,那它能作的东西就太多了(虽然 SW 是用户端本地中间层)
简单举几个例子:
回到最开始,PWA 是一项使人兴奋的技术,可是浏览器兼容有限,所以期待并关注 PWA 技术的发展是颇有必要的!
固然,能推进就更好了!好比推进咱们的 X5 内核尽快支持新特性。