Gatsby: Docs should specify to never cache sw.js

Created on 2 Nov 2018  路  12Comments  路  Source: gatsbyjs/gatsby

Followed the documentation for caching js and css files.
Gave all of them public,max-age=31536000,immutable

Now I have to reload a couple of times to see changes to my site do to sw.js also gets these caching headers.

I think the sw.js should be hashed also in order to give me new results when the site updates or am I wrong?

question or discussion

Most helpful comment

This is my setting for Netlify, which works really well:

   {
      resolve: `gatsby-plugin-netlify`,
      options: {
        headers: {
          "/*.js": [
            'cache-control: public, max-age=31536000, immutable'
          ],
          "/*.css": [
            'cache-control: public, max-age=31536000, immutable'
          ],
          "/sw.js": [
            'cache-control: public, max-age=0, must-revalidate'
          ],
        }
      }
    }

All 12 comments

We definitely need to do that.

Initial technical problem - we generate sw.js in https://github.com/gatsbyjs/gatsby/blob/00284e08dc38802e42e397208ddd6098327fb91e/packages/gatsby-plugin-offline/src/gatsby-node.js#L118 but register that hardcoded file in https://github.com/gatsbyjs/gatsby/blob/2ba57eac8e0f6987e55ff1436b299e5a4063e8bc/packages/gatsby/cache-dir/register-service-worker.js#L12, so will need a way to communicate to gatsby location of used service worker.

We could have action registerSWLocation to override default public/sw.js. And in use that value in https://github.com/gatsbyjs/gatsby/blob/a8aa8752818ee2e560b121b53ee1146712e988af/packages/gatsby/src/utils/webpack.config.js#L175-L182 so it's accessible in gatsby runtime

/cc @davidbailey00

Generally people say to just not cache SW files but hashing names could be easier. Though I vaguely remember something saying you can't do that but I might be wrong.

Also of interest https://stackoverflow.com/questions/38843970/service-worker-javascript-update-frequency-every-24-hours/38854905#38854905

Yeah, I think you do need to just not cache SW files as the SW looks for the same file name to see if the SW file has been updated.

We need to update the caching docs to make clear not to cache the SW file as well as the plugin-offline README

https://developers.google.com/web/updates/2018/06/fresher-sw

So is there a better way to do it? Like putting that js in the index.html file as this should not be cached?

You add a cache rule explicitly for the SW file to not cache it.

I agree with @KyleAMathews on this - common practice is to have your service worker consistently at /sw.js but disable HTTP caching. Leaving open for discussion, and since we need to improve the docs

So setting /sw.js to "cache-control: public, max-age=0, must-revalidate" should be good?

Yup!

@KyleAMathews @ahansson89 I can't find in the docs how to best do this with Gatsby. How do you set the cache-control header in gatsby for the sw.js file?

We are running into an issue were the production builds stick on the older versions. I'm hoping this will solve the issue so that when we do a production build the users get the newest version?

Thanks!

@systemlevel This isn't actually something controlled by Gatsby - it depends on whichever web server you're using to host the generated files. If you're using something like Netilfy, you don't have to do anything because all files are revalidated upon request. For others, look up the relevant guides - e.g. for nginx.

The purpose of this issue is to update our docs to specify which files should be cached, but not to tell users how to do this, since it depends on which web server you're using.

This is my setting for Netlify, which works really well:

   {
      resolve: `gatsby-plugin-netlify`,
      options: {
        headers: {
          "/*.js": [
            'cache-control: public, max-age=31536000, immutable'
          ],
          "/*.css": [
            'cache-control: public, max-age=31536000, immutable'
          ],
          "/sw.js": [
            'cache-control: public, max-age=0, must-revalidate'
          ],
        }
      }
    }

For those who are unsure whether an aggressively cached sw.js is indeed the issue, checking "Update on reload" under Chrome Dev Tools helped a lot: https://stackoverflow.com/questions/40783790/disable-service-workers-when-in-development-mode

Was this page helpful?
0 / 5 - 0 ratings