初探PWA

9次阅读

共计 2853 个字符,预计需要花费 8 分钟才能阅读完成。

引言
PWA(Progressive web apps, 渐进式 Web 应用),近两年被炒的十分火爆,它有什么优点呢?

可以生成桌面小图标,不需要打开浏览器,方便用户访问
通过网络缓存提升页面访问速度,达到渐进式的页面甚至离线访问,提升用户体验
实现类似 app 的推送功能,生成系统通知推送给用户

上面的这些优点足以让它吸引大量的开发者来探索和应用,毕竟对于 web 应用来说,用户体验才是检验 web 应用的好坏的至高标准,而 PWA 的这些优点恰恰是开发者在开发时一直追求的
Service Worker
service worker 是实现 PWA 的核心,service worker 是一个独立的浏览器线程,不会对当前程序的执行线程造成阻塞,通过 service worker 可以实现页面离线访问、用户消息推送等功能
生命周期
service worker 生命周期完全独立于网页,因此,要想网页中使用 service worker,需要先注册,注册后浏览器会在后台启动相关的安装步骤,一般情况下,我们需要 service worker 缓存一些静态文件,因此安装过程中会对指定的静态文件进行缓存,若缓存成功,则 service worker 安装成功,若中间有任何一个文件缓存失败,则 service worker 安装失败,会在下次重启时再次尝试,下面来看一个具体的生命周期图(来源 [https://developer.mozilla.org…]()):
简单应用
看来上面的介绍,是不是跃跃欲试呢?接下来将用代码来简单使用一下 service worker,缓存页面中的 css、js 文件,具体例子:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”>
<meta name=”viewport” content=”width=device-width,initial-scale=1.0″>
<link rel=”stylesheet” type=”text/css” href=”/cache1.css”>
<title>pwa</title>
</head>
<body>
<div id=”app”>test1</div>
<!– built files will be auto injected –>
<script src=’/cache1.js’></script>
<script>
if (‘serviceWorker’ in navigator) {
window.addEventListener(‘load’, function () {
navigator.serviceWorker.register(‘/sw.js’).then((registration) => {
console.log(‘Service Worker Registration’)
}, (err) => {
console.log(err)
})
})
}
self.addEventListener(‘fetch’, () => {
console.log(‘ss’)
})
</script>
</body>
</html>
sw.js:
var cacheName = ‘my-cache’
var cacheList = [‘/cache1.css’, ‘/cache1.js’]
self.addEventListener(‘install’, function(event) {
event.waitUntil(
// 安装成功后向 caches 中存入需要缓存的文件
caches.open(cacheName).then(function (cache) {
return cache.addAll(cacheList)
})
)
});
// 监听 service worker fetch
self.addEventListener(‘fetch’, function (event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// 在缓存中查找到匹配的请求,就从缓存返回
if (response) {
console.log(response)
return response;
}
// 缓存中没有查找到对应请求,继续网络请求
return fetch(event.request);
}
)
);
})
如上例所示,利用 service worker 缓存了页面请求中 cache1.js、cache1.css,然后再刷新一下网页,网页请求就会变成下图这样:在网络请求面版可以很清楚看到这两个文件是从 ServiceWorker 中请求出来的,可能有些人对 caches 这个缓存对象还不是很了解,这有一篇文章可以帮助大家理解:传送门
vue-cli3 中的 pwa
vue 最新脚手架中集成了 pwa 的插件,将 pwa 的实现变得更加的简单,只需要在 vue.config.js 文件中配置 pwa 属性就可以自动生成对应的 service-worker.js 配置文件,配置参考:传送门,这里面最核心的就是集成了 google 团队开发的 Workbox,因此关于更加详细的 pwa 配置可以参考:传送门,这里面包含 workbox 所有配置项,这里面需要关注的是 runtimeCaching 属性,这个属性提供五种缓存策略:

CacheFirst:优先取缓存中的数据,若没有则请求网络,请网络也失败就会报错
CacheOnly:只从缓存中获取,若没有则报错
NetworkFirst:优先从网络获取,若没有则从缓存中获取,缓存获取失败则报错
NetworkOnly:只从网络获取,若没有则报错
StaleWhileRevalidate:同时从网络与缓存获取,如果缓存可用,取缓存数据,否则从网络中请求,同时缓存会随着网络请求而更新

更加详细的缓存策略可以参考传送门,这里的缓存策略还需要注意的一个问题就是同源策略的问题,一般情况下 workbox 不会缓存跨域的资源请求,因为在缓存跨域资源时,workbox 无法检测跨域请求是否成功,如果失败,用户将无法获取响应数据,但是在 NetworkFirst 和 StaleWhileValidate 策略下,可以缓存跨域资源,因为这两个策略的缓存会定期更新,即便出现失败请求,缓存的时间也是短暂的,具体详情可以参考传送门
兼容性
ServiceWorker 这么牛,是不是就没有什么问题了呢,它最大的问题应该就是它的兼容性问题了,iOS11.3 之前都不支持,具体详情参考:传送门,因此 vue 脚手架在集成时默认在 ios 下是关闭的
总结
PWA 确实是当下很热门的技术,因为它提升了 web 应用的体验,甚至达到可以和原生 app 体验相提并论,但是它的问题就是兼容性问题,相信如果兼容性问题得到解决,这种技术一定会被大面积推广到实际应用,希望通过这篇文章能对大家了解这门技术有一定的帮助。如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞。

正文完
 0