前端缓存-workbox缓存策略

3,272 阅读2分钟

workbox 是 GoogleChrome 团队推出的一套 Web 静态资源本地存储的解决方案。workbox这个库是基于 servicework 的 fetch event 和cache API。

想要使用 workbox,首先需要注册 Service Worker 并创建 sw.js 文件

// Check that service workers are registered
if ('serviceWorker' in navigator) {
  // Use the window load event to keep the page load performant
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('./sw.js');
  });
}

在sw.js文件中,首先需要引入 workbox ,接下来就是设置缓存策略。workbox一共有5种缓存策略如下:

  1. stateWhileRevalidate:当请求的路由有对应的 Cache 缓存结果就直接返回,在返回 Cache 缓存结果的同时会在后台发起网络请求拿到请求结果并更新 Cache 缓存,如果本来就没有 Cache 缓存的话,直接就发起网络请求并返回结果,这对用户来说是一种非常安全的策略
  2. networkFirst:当请求路由是被匹配的,就采用网络优先的策略,也就是优先尝试拿到网络请求的返回结果,如果拿到网络请求的结果,就将结果返回给客户端并且写入 Cache 缓存,如果网络请求失败,那最后被缓存的 Cache 缓存结果就会被返回到客户端,这种策略一般适用于返回结果不太固定或对实时性有要求的请求,为网络请求失败进行兜底。
  3. cacheFirst:当匹配到请求之后直接从 Cache 缓存中取得结果,如果 Cache 缓存中没有结果,那就会发起网络请求,拿到网络请求结果并将结果更新至 Cache 缓存,并将结果返回给客户端。这种策略比较适合结果不怎么变动且对实时性要求不高的请求
  4. networkOnly:强制使用正常的网络请求,并将结果返回给客户端,这种策略比较适合对实时性要求非常高的请求。
  5. cacheOnly:直接使用 Cache 缓存的结果,并将结果返回给客户端,这种策略比较适合一上线就不会变的静态资源请求。
    如果以上策略都不满足需求,还可以自定义策略
try {
    importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js');
    // html css 如果想让页面离线可以访问,使用 NetworkFirst或cacheFirst,如果不需要离线访问,使用 NetworkOnly
	workbox.routing.registerRoute(
	  new RegExp('.*\.html|css'),
	  workbox.strategies.NetworkFirst()
	); 

	// js 文件名中带了 Hash 版本号,那可以直接使用 Cache First 策略, 否则使用NetworkFirst
	workbox.routing.registerRoute(
		new RegExp('.*\.js'),
		workbox.strategies.cacheFirst({
			// Use a custom cache name
			cacheName: 'js-cache',
		})
	);
    //图片一般一段时间内不会改变,建议使用catchFirst
	workbox.routing.registerRoute(
		// Cache image files
		/.*\.(?:png|jpg|jpeg|svg|gif)/,
		// Use the cache if it's available
		workbox.strategies.cacheFirst({
			// Use a custom cache name
			cacheName: 'image-cache',
			plugins: [
				new workbox.expiration.Plugin({
					// Cache only 20 images
					maxEntries: 20,
					// Cache for a maximum of a week
					maxAgeSeconds: 7 * 24 * 60 * 60,
				})
			],
		})
	);
}catch(err) {
    console.log('workbox引入失败')
}

可以根据自己的具体需求来设置缓存策略