【问题标题】:How to cache a React app with service workers如何使用服务人员缓存 React 应用程序
【发布时间】:2020-12-20 08:15:16
【问题描述】:

我只是想知道如何处理这个问题。我想缓存我的整个应用程序。 我尝试过类似的方法,但似乎不起作用

self.addEventListener('install',(e)=>{
  console.log('installed');

})

self.addEventListener('activate',(e)=>{
  console.log('activated');
  self.skipWaiting();
})

self.addEventListener('fetch',(e)=>{
  e.respondWith(
    fetch(e.request)
      .then(res=>{
        const resClone = res.clone();
        caches.open(cacheName).then(cache=>{
          cache.put(e.request, resClone);
        })
        return res;

      }).catch(err => {
        console.log('no connection');
        caches.match(e.request).then(res => { return res })
      })
  )
})

有谁知道如何解决这个问题?

【问题讨论】:

    标签: reactjs progressive-web-apps service-worker


    【解决方案1】:

    一种幼稚的方法是查看页面源并检查 react 正在使用哪些 js、css 文件并手动缓存它们。

    这在生产中不起作用,您必须手动检查构建目录中的文件并更新 service-worker

    或者更好和更明智的做法是使用workbox(来自谷歌的一个 npm 包)来处理所有这些混乱

    【讨论】:

      【解决方案2】:

      这对我有用,

      self.addEventListener("fetch", function(event) {
        event.respondWith(
          caches.match(event.request).then(function(response) {
            if (response) {
              return response;
            } else {
              return fetch(event.request)
                .then(function(res) {
                  return caches.open(CACHE_NAME).then(function(cache) {
                    cache.put(event.request.url, res.clone());
                    return res;
                  });
                })
               
            }
          })
        );
      });

      这告诉服务工作者首先从缓存中读取,然后如果没有来自缓存的响应则网络。 要记住一件事,这不会检查对文件所做的任何更新。如果您更改您的反应代码,服务工作者将加载它在缓存中的先前文件。

      要解决这个问题,您可以使用工作箱的 staleWhileRevalidate,只要有网络连接,它就会更新缓存。

      一个不太方便的解决方案是在服务工作者激活时删除缓存:

      self.addEventListener('activate', function(event) {
        event.waitUntil(
          caches.keys()
          .then(function(keyList) {
            return Promise.all(keyList.map(function(key) {
              return caches.delete(key);
      
            }));
          })
        );
        return self.clients.claim();
      });

      每当安装新的 service worker 时,缓存都会被移除并创建一个新的。

      【讨论】:

      • 很有趣,谢谢,我会调查一下。你能明白为什么我的不工作吗?
      • @ST 您在 then 提取块(e.request)之外返回 res 。这使得返回的 res 未定义,因为 res 不在 return 的范围内。
      • 在您发送的示例中 - 如果总是有缓存怎么办? Hpw 你的应用会更新吗?
      • 这就是这种方法的问题。即使您更改应用程序,Service Worker 仍会加载它在缓存中的旧版本,因此您的更改不会出现在浏览器中。您可以手动删除包含旧文件的缓存,也可以设置服务工作者以在激活后删除缓存,但您需要更改服务工作者中的某些内容以强制浏览器重新安装服务工作者并运行再次激活码并删除旧缓存。
      • 在开发过程中,这种缓存方法远非理想。但是,在已部署的生产构建中,由于您不会进行太多更改,因此此策略更有意义。但是由于我之前提到的原因,您仍然需要更改 service worker 中的某些内容以确保最终用户将获得最新版本。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 2020-03-14
      相关资源
      最近更新 更多