Javascript 渐进式Web应用上的缓存版本控制
服务工作者缓存的当前最佳实践是什么 在为许多项目使用了服务人员和缓存之后,我们在管理项目的缓存资产时遇到了一些维护难题 在大多数情况下,我们使用的是静态缓存(很可能是我们头疼的原因),我们的sw.js代码非常标准,如下所示:Javascript 渐进式Web应用上的缓存版本控制,javascript,service-worker,progressive-web-apps,Javascript,Service Worker,Progressive Web Apps,服务工作者缓存的当前最佳实践是什么 在为许多项目使用了服务人员和缓存之后,我们在管理项目的缓存资产时遇到了一些维护难题 在大多数情况下,我们使用的是静态缓存(很可能是我们头疼的原因),我们的sw.js代码非常标准,如下所示: var cacheName = 'v1:static'; // cache static assets during install phase self.addEventListener('install', function (e) { e.waitUntil
var cacheName = 'v1:static';
// cache static assets during install phase
self.addEventListener('install', function (e) {
e.waitUntil(
caches.open(cacheName).then(function (cache) {
return cache.addAll([
'./',
'./css/style.css',
'./css/vendor.css',
'./js/build/script.min.js',
'./js/build/vendor.min.js'
]).then(function () {
self.skipWaiting();
});
})
);
});
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).then(function (response) {
if (response) {
// retrieve from cache
return response;
}
// fetch as normal
return fetch(event.request);
})
);
});
一旦我们发布了新版本的应用程序,问题就开始了,我们需要为用户使缓存失效
建议使用哪些方法更新缓存?我知道有人或开发人员手动更新cacheName变量(或者可能通过任务运行程序)。还有其他选择吗?有没有办法只使一个文件而不是整个缓存失效
谢谢我建议您对项目进行资产评估。从动态资产中确定静态资产。一旦确定了纯静态的,就要对其进行预切 有两种方法可以做到这一点。1) 使用或2)手动更新浏览器的service worker文件的版本号以进行更新 我知道您在使缓存和所有内容无效时所经历的痛苦。您可能想要尝试/实现 软件工具箱方法
const OFFLINE_URL = '/pages/offline/';
importScripts('sw-toolbox.js');
self.toolbox.precache([
<PATH_TO_STATIC_ASSET>
'manifest.json',
OFFLINE_URL,
'/'
]);
self.toolbox.router.default = self.toolbox.networkFirst;
self.toolbox.router.get('/(.*)', function (req, vals, opts) {
return self.toolbox.networkFirst(req, vals, opts)
.catch(function (error) {
if (req.method === 'GET' && req.headers.get('accept').includes('text/html')) {
return self.toolbox.cacheOnly(new Request(OFFLINE_URL), vals, opts);
}
throw error;
});
});
const OFFLINE_URL='/pages/OFFLINE/';
importScripts('sw-toolbox.js');
self.toolbox.precache([
'manifest.json',
离线链接,
'/'
]);
self.toolbox.router.default=self.toolbox.networkFirst;
self.toolbox.router.get('/(.*),函数(req、vals、opts){
返回self.toolbox.networkFirst(req、VAL、opts)
.catch(函数(错误){
if(req.method==='GET'&&req.headers.GET('accept')。包括('text/html')){
返回self.toolbox.cacheOnly(新请求(脱机URL)、VAL、opts);
}
投掷误差;
});
});
谷歌服务人员样板文件-
这个也很直截了当。唯一的缺点是,在每次部署时,您都必须为安装的服务工作者更新CACHE\u版本
,以便自动更新
还请注意,还有一个问题。我还没有玩过那么多,所以我的方法可能已经过时了。他们说这是precache和toolbox的后代,我认为最简单的方法是更新ServiceWorkers JS文件中的CACHE\u名称,以便再次安装它。通过
/path/to/script.JS?v=1.2.3
加载脚本并将v参数链接到项目版本号的情况并不少见。如果您的缓存最终将过期(应该过期),那么您就不必费心删除旧条目。您提到要注意sw precache
,它适用于您正在描述的用例。你不想用它有什么原因吗?(我是作者,我很好奇是否有你担心的缺点。)@JeffPosnick我认为它很好地满足了它的目的(并且允许你在不知道引擎盖下发生了什么的情况下实施预加工);但由于服务人员相对较新,我个人现在更喜欢编写大多数引导代码。