Web 应用的现状html
针对以上问题,结局方案出现了PWA前端
PWA全称Progressive Web App,即渐进式WEB应用。 一个 PWA 应用首先是一个网页, 能够经过 Web 技术编写出一个网页应用. 随后添加上 App Manifest 和 Service Worker 来实现 PWA 的安装和离线等功能web
Service Worker 是浏览器在后台独立于网页运行的脚本,它打开了通向不须要网页或用户交互的功能的大门。 Service Worker从英文翻译过来就是一个服务工人,服务于前端页面的后台线程,基于Web Worker实现。有着独立的js运行环境,分担、协助前端页面完成前端开发者分配的须要在后台悄悄执行的任务。编程
主要包含六种状态 解析成功(parsed),正在安装(installing),安装成功(installed),正在激活(activating),激活成功(activated),废弃(redundant)。json
// main.js
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/sw.js')
.then(function (registration) {
// 注册成功
console.log('ServiceWorker registration successful with scope: ', registration.scope);
if (registration.installing) {
// Service Worker is Installing
console.log('Service Worker is Installing')
} else if(registration.waiting) {
// 这是更新新版本或自动更新缓存的绝佳时机
/*
* 当前没有激活的 worker
* 若是在 Service Worker 的脚本中 self.skipWaiting() 被调用
* 若是用户访问其余页面并释放了以前激活的 worker
* 在一个特定的时间过去后,以前一个激活的 worker 被释放
*/
console.log('Service Worker is Waiting')
} else if(registration.active) {
// 激活成功, Service Worker 是一个能够彻底控制网页的激活 worker
console.log('Service Worker is active')
}
})
.catch(function (err) {
// 注册失败:(
console.log('ServiceWorker registration failed: ', err);
});
});
}
window.onload = function() {
document.body.append('PWA!')
}
复制代码
在代码中的具体实现segmentfault
// sw.js
/*
sw.js 控制着页面资源和请求的缓存
*/
// 监听 service worker 的 install 事件,
// 对站点离线访问最关键的资源 URL 列表,它们一般也是关键请求链包含的文件,并将其缓存进 caches 中
self.addEventListener('install', function (e) {
// 若是监听到了 service worker 已经安装成功的话,就会调用 event.waitUntil 回调函数
e.waitUntil(
caches.open('v1').then(cache => {
// 经过 cache 缓存对象的 addAll 方法添加 precache 缓存
return cache.addAll([
'/main.js',
'/index.html',
'/'
]);
}).then(function() {
// 跳过waiting,直接进入active
console.log('Skip waiting!')
return self.skipWaiting()
})
);
});
/*
事件回调是一个管理老旧缓存的好地方
在通常 PWA 中,咱们能够结合版本号和缓存名,及时删除过时缓存
*/
self.addEventListener('activate', function(e) {
const cacheStorageKey = 'v1'
e.waitUntil(
Promise.all(
caches.keys().then(cacheNames => {
return cacheNames.map(name => {
if (name !== cacheStorageKey) {
return caches.delete(name)
}
})
})
).then(() => {
console.log('Clients claims.')
// 经过clients.claim方法,更新客户端上的server worker
return self.clients.claim()
})
)
})
/*
对不一样资源类型应用不一样的请求/缓存策略
看看这些请求所请求的文件在咱们的缓存里有没有,有的话就直接从缓存里拿,不用下载了。
这也是PWA最重要的功能之一
*/
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request)
.then(function (response) {
// 检测是否已经缓存过
if (response) {
return response;
}
var fetchRequest = event.request.clone();
return fetch(fetchRequest).then(
function (response) {
// 检测请求是否有效
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
var responseToCache = response.clone();
caches.open('v1')
.then(function (cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});
// 推送消息
self.addEventListener('message', function(event) {
// Do stuff with postMessages received from document
console.log("SW Received Message: " + event.data);
});
复制代码