什么是PWA
Progressive Web Application,全称“渐进式网页应用”,是Google 在2016年提出的概念,2017年落地的web技术。目的是在移动端利用提供的标准化框架,在网页应用中实现和原生应用相近的用户体验的渐进式网页应用。
引用官方介绍:
1.可靠——即时加载,即使在不确定的网络条件下也不会受到影响。
当用户从主屏幕启动时,service work可以立即加载渐进式Web应用程序,完全不受网络环境的影响。service work就像一个客户端代理,它控制缓存以及如何响应资源请求逻辑,通过预缓存关键资源,可以消除对网络的依赖,确保为用户提供即时可靠的体验。
2.快速
据统计,如果站点加载时间超过3s,53% 的用户会放弃等待。页面展现之后,用户期望有平滑的体验,过渡动画和快速响应。
3.沉浸式体验—— 感觉就像设备上的原生应用程序,具有沉浸式的用户体验。
渐进式Web应用程序可以安装并在用户的主屏幕上,无需从应用程序商店下载安装。他们提供了一个沉浸式的全屏幕体验,甚至可以重新与用户接触的Web推送通知。Web应用程序中,可以通过manifest.json控制应用程序的显示方式和启动方式,指定主屏幕图标、启动应用程序时要加载的页面、屏幕方向,甚至可以指定是否显示浏览器Chrome。
核心 Service Workers
Service worker是一个JavaScript worker 运行在 web worker上下文,因此它不能直接访问DOM,service worker 可以通过postMessage 接口与跟其相关的页面进行通信,发送消息,从而让这些页面在有需要的时候去操纵 DOM 。不同于主线程,它运行在其他线程中,所以不会造成主线程阻塞。它设计为完全异步,同步API(如XHR和localStorage)不能在service worker中使用。
Service workers 本质上充当Web应用程序(服务端)与浏览器(客户端)之间的代理服务器。
可以提供有效有效的离线体验,拦截网络请求。还可以推送通知。
使用注册Service worker
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker.register("/sw.js", {}).then(registration => {
console.log("register succces...")
}, err => {
console.log("register error...", err)
})
})
}
离线功能
Service Worke 通过缓存资源和拦截网络请求来提供离线功能,这些请求可以与先前缓存的资源一起使用,而不是重新请求服务器。
我们可以从中得出两个步骤:
-预缓存
-从缓存中处理请求
这两个步骤都利用了Cache API,它由 Web Workers 和浏览器使用,并且为我们提供了用于网络请求的存储机制。
对 Web 和服务工作人员上下文的 localStorage 访问被阻止,以防止并发性问题。作为一种替代方案,IndexedDB 可以用于存储大量数据。
预缓存
描述了在 Service Worker 处于激活状态之前下载和缓存文件。 在的“install ”步骤中完成的。 一旦 Service Worker 处于激活状态,将准备为缓存中的文件提供服务。
this.addEventListener('install', function (event) {
/* 通过这个方法可以防止缓存未完成,就关闭serviceWorker */
event.waitUntil(
/* 创建一个名叫V1的缓存版本 */
caches.open('v1').then(function (cache) {
/* 指定要缓存的内容,地址为相对于跟域名的访问路径 */
return cache.addAll([
'./index.html'
]);
})
);
});
从缓存中处理请求
在此阶段,我们已经将所有应用程序代码存储在缓存中,并且Service Worker 已处于激活即运行于浏览器后台。
注册监听 fetch 事件并从缓存中返回结果。可以通过 fetch 事件可以拦截到当前作用域范围内的 http/https 请求,并且给出自己的响应。结合 Fetch API ,可以简单方便地处理请求响应,实现对网络请求的控制。
/* 注册fetch事件,拦截全站的请求 */
this.addEventListener('fetch', function(event) {
event.respondWith(
/* 在缓存中匹配对应请求资源直接返回 */
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});
这里实现了一个缓存优先、降级处理的策略逻辑:监控所有 http 请求,当请求资源已经在缓存里了,直接返回缓存里的内容;否则使用 fetch API 继续请求,如果是 图片或 css、js 资源,请求成功后将他们加入缓存中;如果是离线状态或请求出错,则降级返回预缓存的离线内容。
注:
在Firefox浏览器的用户隐私模式,Service Worker不可用
网站必须使用 HTTPS。除了使用本地开发环境调试时(如域名使用 localhost)