JavaScript轻应用PWA实践全过程

【JavaScript轻应用PWA实践全过程】

JavaScript轻应用PWA实践全过程

文章插图

前言
PWA (Progressive web Apps),渐进式Web 应用,又称轻应用,是一种纯html5网站却可实现Native App的屏幕入口、离线缓存、消息推送等功能的W3C标准的技术组合 。
PWA的完整教程网上比较少(中文版写的比较好的:https://lavas.baidu.com/pwa,不过里面实践比较少,很多坑没踩出来),故写下这篇文章帮助需要的人 。PWA按照以上三个主要功能,分别用到三种技术:
manifest.json 实现APP入口
Service Worker 离线缓存
Web Push 消息推送
它们都需要在https基础上才能使用 。
PWA并不是新技术,早在2014年即有人提出草案并做出了demo,比微信小程序还早 。随着标准被新版本浏览器支持,17年国内也有很多团队开始实践,而18年前端Chrome力推的两大前端技术就是PWA与Flutter 。不同的是,PWA是力求不改变原站代码的基础上,逐步的实现轻应用的功能;而Flutter是用Dart重写跨平台的APP,一套代码,多端使用 。
理想很美好,现实很骨感 。PWA在国内实践并不算多,由两个重要原因:1. 国内浏览器对之支持不太好 。2. web push功能在国内遇阻,因为web push由浏览器自己的消息推送服务器实现的,比如Chrome的消息推送国内常常block 。所以,为了更好的体验,中国局域网用户推荐使用Firefox, 其他互联网用户推荐使用Chrome(测试后发现,国内局域网也是部分能收到Chrome的推送) 。
manifest.json 实现APP入口
manifest.json是一个位于网站对外根目录的配置文件(一般与index.html在同级目录),开发者只需按照 W3C定义好的属性https://www.w3.org/TR/appmanifest/设置即可,本文不做详述,只列举几个常用的属性:
JavaScript轻应用PWA实践全过程

文章插图
 
手机用户可以用浏览器的“添加至主屏幕”,上述配置在此处生效,并且手机默认也会提示用户去添加 。
开发者可以在Chrome devTools 的Application的Manifest中查看当前网站的匹配,它还可以提示配置错误 。
Service Worker 离线缓存
Service Worker 是运行于浏览器后台的独立线程,它注册在指定源的路径下,不仅不同网站都有独立的Worker,同一个网站不同的路径下也可以注册不同的Worker,一旦注册则是永久的,除非手动卸载,在Chrome devTools 的Application的Service Worker中可以查看/卸载 。
可以发现Service Worker与Web Worker非常类似,都是独立于主线程之外的独立线程,都不能使用Window之类的浏览器内置对象,都不能操作DOM,都是异步的等 。不仅如此,Service Worker还被增强了,它可以拦截/代理浏览器的请求,可以使用Cache Storage缓存页面,可以监听服务器推送的消息并且向在浏览器给用户推送消息等 。
使用Service Worker之前,我们先了解一下它的生命周期:
JavaScript轻应用PWA实践全过程

文章插图
 

JavaScript轻应用PWA实践全过程

文章插图
 
以上代码写在一个名为service_worker.js的脚本里,但它是独立运行的,我们又需要写引用/执行这个脚本的脚本 service_worker_before.js 。
入口文件service_worker_before.js 注册Service worker :
JavaScript轻应用PWA实践全过程

文章插图
 
注册代码很简单,需注意几点:
a. scope是Worker的源的范围,默认值为service_worker.js所在目录 。
b. 这里命名了swVersion 即Service Worker version,用它记录与升级我们的Worker, 并把这个值传入Worker中,控制着缓存的版本,我们让缓存与Worker一起升级 。但有一个问题,我们的页面是会被缓存的,这时无论我们的版本号是多少,都无法让其升级,所以对于升级代码文件,我们不应该使用离线缓存,而应该使用浏览器默认的缓存,也可以直接设置不缓存 。
c. 升级文件指 manifest.json, service_worker.js,service_worker_before.js 。比如在Nginx中可以设置不要缓存(未实践):
JavaScript轻应用PWA实践全过程

文章插图
 
外部入口注册后,我们可以在service_worker.js中写Worker内部事件了:
Worker 安装
JavaScript轻应用PWA实践全过程

文章插图
 
如果追求快速更新,我们可以跳过等待,直接激活,即我们打开的新页面都是使用最新的Worker代码 。


推荐阅读