PWA-离线优先中的缓存模式

本文最后更新于:a few seconds ago

什么是离线优先

离线优先允许用户在网络不好的情况下,也能放心的使用这个应用,并且的数据不会丢失。
离线优先意味着,总是基于当前网络,获得最佳体验。


常用的缓存模式 🍭

下面来看几种常见的缓存模式。

仅缓存

这种模式对静态资源非常实用,代码如下:

self.addEventLister("fetch",function(event){
    event.respondWith(
    caches.match(event.request);
    );
});

缓存优先,网络作为回退方案

这个模式也会从缓存中相应请求。然而,如果在缓存中找不到内容,service worker 会从网络中请求并返回:

self.addEventListener("fetch",function(event){
    event.respondWith(
        caches.match(event.resquest).then((response)=>{
            return response|| fetch(event.request);
        })
    )
});

仅网络

经典的web模型,尝试从网络中请求,网络不通,则请求失败。

self.addEventListener("fetch",function(event){
    event.respondWith(
    fetch(event.request)
   );
});

网络优先,缓存做为回退方案。

总是向网络发起请求,请求失败则返回缓存中的版本。

self.addEventListener("fetch",function(event){
    event.respondWith(
        caches.match(event.resquest).catch(()=>{
           return caches.match(event.request);
        })
    )
});

网络优先,缓存作为回退方案,通用回退作为兜底方案

self.addEventListener("fetch",function(event){
    event.respondWith(
        caches.match(event.resquest).catch(()=>{
           return caches.match(event.request).then((response)=>{
            return response || caches.match("/generic.png");
           });
        })
    );
});

按需缓存

对于不经常改变的资源以及service worker install 事件期间不想缓存的资源,我们可以扩展缓存优先,网络作为回退方案的模式。将网络返回的请求保存到缓存中。

self.addEventListener("fetch", function (event) {
    event.respondWith(
        caches.open('cache-name').then((cache) => {
                return caches.match(event.request).then((cachedResponse) => {
                    return cachedResponse || fetch(event.request).then((networkResponse){
                        cache.put(event.request, networkResponse.clone());
                        return networkResponse;
                    })
                });
            })
    );
});

在响应保存到缓存中时,我们对其使用了一个clone方法。

    fetch(event.request).then((networkResponse){
        cache.put(event.request, networkResponse.clone());
        return networkResponse;
    });

这是因为我们打算不止一次使用它(将其放入缓存并使用它来相应事件)。这样就要确保使用clone命令来复制它。


缓存优先,网络作为回退方案,并频繁更新缓存

对于经常修改的资源(如用户头像),我们可以修改缓存优先,网络作为回退方案的模式。即使在缓存中找到,也总会从缓存中请求资源。

self.addEventListener("fetch", function (event) {
    event.respondWith(
        caches.open('cache-name').then((cache) => {
            return caches.match(event.resquest).then((cachedResponse) => {
                    const fetchPromise = fetch(event.request).then((networkResponse){
                        cache.put(event.request, networkResponse.clone());
                        return networkResponse;
                    });
                    return cachedResponse || fetchPromise;
                });
            })
    );
});

网络优先,缓存作为回退方案,并频繁更新缓存。

该模式总会试图从网络中获取最新版本,仅在网络请求失败的时候才回退到缓存版本。
每当网络访问成功时,会将当前缓存更新为视为网络响应的内容。

self.addEventListener("fetch", function (event) {
    event.respondWith(
        caches.open('cache-name').then((cache) => {
            return caches.match(event.resquest).then((cachedResponse) => {
                cache.put(event.request, networkResponse.clone());
                return networkResponse;
                }).catch(()=>{
                    return cache.match(event.request);
                });
            })
    );
});

总结一下缓存策略 🎄

  1. 使用缓存优先,网络作为回退方案,并频繁更新缓存模式返回index.html文件。
  2. 使用缓存优先,网络作为回退方案,返回首页需要展示的所有静态文件。
  3. 从网络中返回谷歌地图的javascript文件,如果请求失败,则返回一个代替的脚本。
  4. 使用网络优先,缓存作为回退方案,并频繁更新缓存模式,返回events.json文件。
  5. 使用按需缓存模式返回事件的图片文件,如果网络不可用并且图片没有缓存,则退回到默认的通用图片。
  6. 数据分析请求直接通过,不做处理。

结束🐟

握手西风泪不干,年来多在别离间。「于中好·握手西风泪不干」——纳兰性德