最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React application with Service Worker - Force update of browser cache on new version - Stack Overflow

programmeradmin2浏览0评论

My app is written in Reac / Redux and uses Workbox to generate my service worker. This works - I can confirm revision is updated in the generated service worker when running "workbox inject:manifest".

However, I have noticed clients are not updating the cache after a new release, new code will only load after several refreshes. For each release I have confirmed that the revision is updated.

The things I have tried so far to force the browser to clear the cache after a new release are:

  • Implemented skipWaiting() in my ServiceWorker - shows update alert correctly
  • Added cache headers to disable caching of the serviceWorker.js and css files (see below)
  • Added [contenthash] to all my bundle files in Webpack and updated index.html accordingly for each release

Cache headers

<IfModule mod_headers.c>
  Header unset ETag
    
  <IfModule mod_alias.c>
    # disable browser cache for serviceWorker.js file
    <FilesMatch "^(serviceWorker.js)$">
      Header unset Expires
      Header set Cache-Control "max-age=0"
    </FilesMatch>
    
    <FilesMatch "\.(js|css)$">
      # cache for 24 hours = 86400 seconds
      Header set Cache-Control "max-age=86400, public, no-transform, must-revalidate"
    </FilesMatch>
  </IfModule>
</IfModule>

index.html

...
<body style="overflow: hidden">
    <div id="app"></div>
    <script src="/dist/main.bundle.aae6d2bb162cbee13899.js"></script>
    <script src="/dist/0.bundle.aaa837f16bb646266d99.js"></script>
    <script src="/dist/1.bundle.aa653fe9abbe232be599.js"></script>
    <script src="/dist/2.bundle.aa3096daabb2d428a899.js"></script>
    <script src="/dist/3.bundle.aa1650fc5bb4e1f1ea99.js"></script>
    <script src="/dist/4.bundle.aae80e50cbb06d5e5599.js"></script>
    <script src="/dist/5.bundle.aa1824b9ebb0cb931b99.js"></script>
    <noscript>
        Sorry, this page requires javascript!
     </noscript>
</body>
</html>

Despite all these solutions the app still caches in all tested browsers (FF, Chrome, Safari) and in the PWA. The cache will only refresh after one or more reloads and/or hard reload.

I have also verified that the bundle file hash have changed for updated code between releases.

Example of old file before code update and deploy

5.bundle.aa1824b9ebb0cb931b99.js

Example of new file after code update and deploy

5.bundle.cae6d2bb162cbee138bc.js

The reference in index.html to the bundle file is updated with the new hash, but the browser still tries to fetch the old file - resulting in fatal error "ChunkLoadError: Loading chunk [n.oldHash] failed.".

Am I doing this wrong? Is there any other way to force the browser (and PWA) to refresh all code after a new release?

Kind regards /K

My app is written in Reac / Redux and uses Workbox to generate my service worker. This works - I can confirm revision is updated in the generated service worker when running "workbox inject:manifest".

However, I have noticed clients are not updating the cache after a new release, new code will only load after several refreshes. For each release I have confirmed that the revision is updated.

The things I have tried so far to force the browser to clear the cache after a new release are:

  • Implemented skipWaiting() in my ServiceWorker - shows update alert correctly
  • Added cache headers to disable caching of the serviceWorker.js and css files (see below)
  • Added [contenthash] to all my bundle files in Webpack and updated index.html accordingly for each release

Cache headers

<IfModule mod_headers.c>
  Header unset ETag
    
  <IfModule mod_alias.c>
    # disable browser cache for serviceWorker.js file
    <FilesMatch "^(serviceWorker.js)$">
      Header unset Expires
      Header set Cache-Control "max-age=0"
    </FilesMatch>
    
    <FilesMatch "\.(js|css)$">
      # cache for 24 hours = 86400 seconds
      Header set Cache-Control "max-age=86400, public, no-transform, must-revalidate"
    </FilesMatch>
  </IfModule>
</IfModule>

index.html

...
<body style="overflow: hidden">
    <div id="app"></div>
    <script src="/dist/main.bundle.aae6d2bb162cbee13899.js"></script>
    <script src="/dist/0.bundle.aaa837f16bb646266d99.js"></script>
    <script src="/dist/1.bundle.aa653fe9abbe232be599.js"></script>
    <script src="/dist/2.bundle.aa3096daabb2d428a899.js"></script>
    <script src="/dist/3.bundle.aa1650fc5bb4e1f1ea99.js"></script>
    <script src="/dist/4.bundle.aae80e50cbb06d5e5599.js"></script>
    <script src="/dist/5.bundle.aa1824b9ebb0cb931b99.js"></script>
    <noscript>
        Sorry, this page requires javascript!
     </noscript>
</body>
</html>

Despite all these solutions the app still caches in all tested browsers (FF, Chrome, Safari) and in the PWA. The cache will only refresh after one or more reloads and/or hard reload.

I have also verified that the bundle file hash have changed for updated code between releases.

Example of old file before code update and deploy

5.bundle.aa1824b9ebb0cb931b99.js

Example of new file after code update and deploy

5.bundle.cae6d2bb162cbee138bc.js

The reference in index.html to the bundle file is updated with the new hash, but the browser still tries to fetch the old file - resulting in fatal error "ChunkLoadError: Loading chunk [n.oldHash] failed.".

Am I doing this wrong? Is there any other way to force the browser (and PWA) to refresh all code after a new release?

Kind regards /K

Share Improve this question edited Dec 1, 2020 at 14:11 Kermit asked Dec 1, 2020 at 11:22 KermitKermit 3,4176 gold badges36 silver badges61 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 2

I followed similar principles as mentioned in this post to clear my cache. I just made the request on a setInterval rather than wrapping the app in a clear cache HOC. https://dev.to/ammartinwala52/clear-cache-on-build-for-react-apps-1k8j the article this links to also has some good examples, it is worth looking at both. https://dev.to/flexdinesh/cache-busting-a-react-app-22lk

Not sure if this is the best approach, but it works for me

There is a trick in order to foce cash , by adding a get parameter for each new version , like this :

<script src="/dist/5.bundle.aa1824b9ebb0cb931b99.js?v=2"></script>

not that the value of v must be changed in every deployment (you can automate it)

发布评论

评论列表(0)

  1. 暂无评论