PWA实践,使用ServiceWork来对网络资源进行缓存。方案是利用google的workbox基础库(包含一系列缓存API),来确定各种资源的缓存策略。
PWA = Https + ServiceWorker(WorkBox、Cache API) + mainifest file
workbox — Spiritual successor to sw-precache with more advanced caching strategies and easy precaching. The Lighthouse Tool by Google.
- workbox-sw.js:https://developers.google.com/web/tools/workbox/modules/workbox-sw
- workbox cache API: https://developers.google.com/web/tools/workbox/guides/get-started(使用PWA需要webpack/rollup等把npm包编译为es5单文件)
- workbox-sw es6源码:https://github.com/GoogleChrome/workbox/blob/v6/packages/workbox-sw/controllers/WorkboxSW.mjs
- 同步官方workbox cnd:https://developers.google.com/web/tools/workbox/modules/workbox-cli(命令:workbox copyLibraries third_party/workbox/)
自己的workbox库:https://lq782655835.github.io/workbox/demos/build-full-sw/src/workbox-v6.1.1/workbox-sw.js
更新本地workbox版本 npm i -g workbox-cli
执行workbox copyLibraries ./src src下即为所有workbox包。
如果是真正在自己应用上使用,需要修改src/workbox-v6.1.1/workbox-sw.js中的
https://storage.googleapis.com/workbox-cdn/releases/6.1.1替换成自己cdn的地址
测试效果:https://lq782655835.github.io/workbox/demos/src/workbox-mobile/index.html
测试源码详细见demos/src/workbox-sw
核心讲解:
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('./sw.js')
})
}
</script>importScripts(
'https://lq782655835.github.io/workbox/demos/build-full-sw/src/workbox-v6.1.1/workbox-sw.js' // 自己库
// 'https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js' // 官方库
);
/* global importScripts, workbox */
if (workbox) {
console.log(`Workbox is loaded 🎉`);
workbox.core.setCacheNameDetails({
prefix: 'workbox-demo',
});
const matchHTML = ({ url }) => {
return ['/', '/index.html'].includes(url.pathname);
};
workbox.routing.registerRoute(
matchHTML,
new workbox.strategies.StaleWhileRevalidate()
);
workbox.routing.registerRoute(
({ url }) => /\.(?:js|css)$/.test(url.pathname),
new workbox.strategies.StaleWhileRevalidate()
);
workbox.routing.registerRoute(
({ url }) => /\.(?:jpg|jpeg|webp|png|gif)/.test(url.pathname),
new workbox.strategies.CacheFirst({
cacheName: 'images-cache',
plugins: [
new workbox.cacheableResponse.CacheableResponsePlugin({
statuses: [0, 200],
}),
],
})
);
} else {
console.log(`Workbox didn't load 😬`);
}