PWA离线应用
-
前端的日益发展,都离不开性能优化的手段,包括 CDN、CSS Sprite、文件的合并压缩、异步加载、资源缓存等等。更多的时候为了减少用户量的请求,于是就有了PWA,秒开网站,离线访问等等的炫酷装B技能。
-
于是就迫不及待想拉开PWA神秘的面纱,使用到下面的:
- vuecli3.0
- register-service-worker
- 一台不太卡的安卓(安卓版本不够高,Chrome不能添加到桌面上)
-
先上图:
vuecli3.0
- vuecli的最新版本vuecli3.1,通过 npm install -g vue[@cli](/user/cli) 来安装
- vuecli3.0多了很多神奇方便的功能,作者应该想要简化开发者的开发过程,有了炫酷的可视化界面GUI,通过 vue ui 可在浏览器查看、安装、管理包等等
- vuecli3.0还集成了service worker、一些常用的语法检测,自动化测试等等的工具
register-service-worker
-
使用过 create-react-app 的小伙伴肯定知道,react官方推荐的脚手架中默认佩带有 register-service-worker的包,经过打包后,额外生成以下文件:
-
`manifest.json: 可配置该应用在浏览器,桌面中的打开方式,应用名字,应用运行动画等等
-
service-worker.js: 可看到被压缩打包好的service worker的安装,激活、卸载等等的功能与配置
-
asset-manifest.json: 离线下强制缓存的文件,使得APP可在离线下运行
-
有关service worker的详细问题可通过以下链接查看:
后端配置
- 离线缓存需要后台配合,通过有效的缓存达到离线的效果,怎样的缓存才是有效的?就是强制缓存啊!
- 强制缓存与协商缓存都为缓存,主要有以下的不同:
- 协商缓存:有缓存,但是会主动请求服务器后,服务器不返回任何资源
- 强制缓存:有缓存,不会请求服务器,使用本地或者内存或者service worker中的缓存
- 先科普下缓存的分布图:
- 在Chrome控制台的 Network 中查看页面加载时所下载的资源,会发现有些资源会有cache from disk、cache from memory等等,还会有些资源直接显示该资源的资源文件大小,那么这是怎么回事呢?
- cache from disk: 这是强制缓存,表示该资源从本地的缓存文件中拉取资源
- cache from memory:这是强制缓存,表示该资源从内存中拉取资源
- 直接显示资源大小:这是协商缓存或者是不存在缓存,每次都是从服务器下载该资源
- 这里就以express为例子,需要设置公用过滤器,为GET请求设置强制缓存,时间为两小时
//以下的Code设置了公用的响应头中返回的强缓存时间、CORS跨域等等
app.all("*", function(req, res, next) {
if(req.path !== "/" && !req.path.includes(".")) {
res.header("Access-Control-Allow-Origin", req.headers["origin"] || "*")
res.header("Access-Control-Allow-Credentials", true)
res.header("Access-Control-Allow-Headers", 'Content-Type,Content-Length, Authorization, authorization,\'Origin\',Accept,X-Requested-With')
res.header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS")
res.header("Content-Type", "application/json;charset=utf-8")
if(req.method.toUpperCase() === "GET"){
res.header("Cache-Control","max-age=7200")
}
}
next()
})
通过设置请求缓存后,静态资源都必须设置为强制缓存,才能达到离线访问的效果。
-
这次采坑中遇到神坑的问题,当服务器设置了响应头
res.header("Access-Control-Allow-Origin", req.headers["origin"] || "*")
后,如果同一个浏览器都是GET到该服务器的请求,则会报错,报错中显示跨域禁止,因为上面设置的强制缓存的原因,浏览器会主动缓存该GET请求,所以缓存中的GET请求的响应头中的Access-Control-Allow-Origin
(设置允许域名跨域)会显示第一次发出GET请求的域名,而第二次同一个浏览器不同的域名去GET这个请求,则Access-Control-Allow-Origin
返回的是第一个请求的域名,所以会报错。 -
最后通过打包后,第一次访问SPA时,service worker会自动缓存该SPA中所需要的资源,而AJAX请求的数据,则是被浏览器主动缓存的,从而可以达到缓存的效果,在安卓的高版本的chrome中,还可以将该SPA像APP一样打包下载到桌面上,有自己的开机动画等等。
-
在评论处感谢
王品洲
的提醒:(PC)Chrome不能添加到桌面上 :可以试试 F12->Application-> Manifest ->Add to homesreen版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: BillsonKam 原文链接:https://juejin.im/post/6844903672518819848