我正在构建具有有限脱机功能的PWA,每次用户访问新的URL时,我都使用此代码将页面内容保存到动态缓存中:
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request)
.then(function(res) {
return caches.open('cache')
.then(function(cache) {
cache.put(event.request.url, res.clone());
return res;
})
})
.catch(function(err) {
console.log( err );
return caches.match(event.request);
})
);
});
这很好,加载页面后,所有资产都会被缓存,并且可以在离线模式下看到。
但是,我也想添加一个选项,当用户重新联机时自动缓存一些更重要的URL。
我通过将URL列表放入数组中,循环遍历并向每个URL发送获取请求,因此可以缓存这些页面而无需用户访问/重新访问该页面。
问题是,当我这样做时,某些页面上的某些资产没有被缓存,例如一页上的google map,是否有一种方法可以模拟对页面的真实访问,从而通过提取请求?
获取代码:
function fillDynamicCache(user_id = false) {
let urls = [
'/homepage',
'/someotherpage',
'/thirdpage',
'/...',
];
urls.map((url, id) => (
fetch(url)
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
console.log( 'in fetch: ' + url );
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
})
));
}
self.addEventListener('message', (event) => {
// refresh cache when user comes back online
if (event.data == 'is_online') {
fillDynamicCache();
} else if (event.data == 'is_updated') {
self.skipWaiting();
通常,如果您有重要的资产要提供给用户,即使他们处于脱机状态,也应该考虑offline first策略,这意味着您在安装服务工作者时预取了这些资源。
通过这种方式,匹配请求将从缓存中得到处理,因为您跳过了整个网络呼叫,因此提高了性能。
如果目标资源倾向于在服务器上频繁更新/更改,那么您可以选择重新验证时过时策略(在从缓存中提供数据之后,SW将使用更新的值更新其值一个来自网络(如果有),甚至网络优先,回退到缓存,如果您想始终提供最新值并仅在网络连接超时或不可用时提供缓存数据,则后者。
I wrote an article about service worker and caching strategies,如果您想更深入地讨论这个话题。