CDN, stylesheets and images in stylesheets

I am hosting my website on Netlify since a little while and with a redesign I deployed yesterday I noticed that the header image is not cached. So on every single page load, that header image is fetched again.

This is the website:

Now, when I go to Apps page for example, I can see that the images in the website content are served through the CDN. I also enabled asset optimization so I assume they are also optimized and all that. I enabled the same thing for the CSS file, but it’s still serving the same old non-minified CSS file. It’s not served from the CDN either. And the background image that’s included via the CSS file is not served from CDN either, and doesn’t have any caching headers or anything.

The source of the website can be found here: It’s a static site generated with a Python library. It’s pure HTML, no JS, no React, etc.

All of our content is served from some CDN :slight_smile: This asset was served from our usual CDN:

We do run several CDN’s, and we additionally leverage cloudfront for any optimized assets (cf [Common Issue] Does Netlify optimize every single asset my site uses?), so perhaps you see some assets coming from cloudfront, but that doesn’t mean the other assets don’t come from our CDN :wink:

1 Like

Well, when I look at the Apps page for example, I can see that the images got rewritten URL’s. So instead of /bla/image.jpg it’s a link to a full http URL to Cloudfront. The same does not happen to the CSS file, so that was why I was assuming that. Sorry for the confusion!

Still, I enabled the CSS minifier in my build settings, but the CSS file it not minified at all. So that is also why I assumed my CSS file was not being processed like the images clearly are. There seems to be a problem somewhere at least, maybe?

The biggest problem by far though: on every page load the header is loaded from scratch again. So every time you open an article you see the header being loaded with a small flash. This honestly bugs me quite a lot :slight_smile: This should all come from the browser’s cache, right? The images on the Apps page for example have the header “public, max-age=31556926” and are indeed fetched from the browser’s cache, but the splash image has the header “public, max-age=0, must-revalidate”. This is another reason why I assumed there was a CDN problem since there is clearly a difference in how the different images get served.

For example if I just hit refresh a few time on, I see the header and the small Apple logo in front of the links refresh, yet the screenshots are there instantaneously. It’s really quite a big difference.

When I refresh I show a 200 and then the image being loaded from the local cache instead of transferring data from our servers (only the header is checked to confirm the etag is the same). All of this happens using HTTP/2 when I check the browser developer tools.

There is more information about the use of the “max-age=0, must-revalidate, public” headers in this Better Living Through Caching blog post.


From a browser point of view, this sounds terrible — the browser has to check in with our servers for every file it wants to load? Even if it is literally just a page reload in an identical browser session 1 second after the last load? Yes! But it isn’t so terrible due to 2 pieces of magic:

  1. Our CDN
  2. Use of HTTP/2

The CDN makes the check-in from the browser fast — it talks with the node closest to it and that node is ready with an instant answer as to whether the content is usable as-is (Etag matches, no deploys or rollbacks have happened). Using HTTP/2, browsers multiplexes these connections so they can all happen within a single connection and you don’t have to do things like negotiate the HTTPS handshake over and over again.

If you see the image being resent each time (which I do not), please let us know. It would help to get HAR file output of what you are seeing if possible too (if you see the full image reloads when you test).

I’m a little bit lost and don’t really know enough about this stuff. But like I said, if I go to the Apps page and press refresh a few time, or if I simply click through the website (go to the articles page, go to an article go back and open another article, etc etc) then I keep seeing the header image refreshing with a small flash. The same thing does not happen to the images that are part of the article content on Apps.

So I don’t know why you are saying that the image it loaded from local cache, yet I keep seeing this behavior. I think it’s because of the different headers (when comparing images that are loaded via an img tag vs images loaded via the stylesheet), and I would love to solve this somehow, because this flashing header image is driving me nuts while browsing the website.

Can you confirm that you at least see this flashing header behavior the same as I am? I’m using Safari on macOS btw.

Hi @Loopwerk, I am seeing no flashing header at all. The reloading looks absolutely seamless to me. Can you give more information on which browsers you have tested - more than just safari? Are you experiencing cache issues with any other sites or just this one? @luke @Dennis , do you see a flashing header when the site is loaded?

I have installed Chrome to verify and yea… all looks totally fine there. In Safari it’s pretty bad though! I can maybe make a video recording if you need to see it.

Update: video on

Hmm - that is a little annoying, I agree. I would encourage you to reach out to some Safari developer communities who may be more familiar with the issue?

Given that it doesn’t seem to be CDN/Netlify related specifically (as we know that it works acceptably on Chrome) our hands are a little bit tied as to what we can do to help. Have you tested it on firefox, or edge? What about trying it on a different hosting service and seeing if you see the same issue?

That said, if you do find a solution for it, please let us know what you were able to figure out, and if we have any other ideas we will keep thinking about potential solutions and update this thread.

1 Like

Exact same issue in Firefox.

That is so strange. We are all wracking our brains over here and are not sure why you might be seeing this. We haven’t had reports of something like this before. How big is the image in KB? What about in dimensions? (ie. width and height?) have you tried hosting it somewhere else and seeing if the same issue arises?

The image is 179 KB, 1500 × 1000 pixels.
I have not tried hosting it somewhere else, no. Don’t really have time to figure out how and where else to host it, sorry.

Same problem on Edge by the way, but there it’s a problem with all images, also the ones in the html content as img tags (which are not a problem in Safari or Firefox).


I checked with chrome dev tools open and indeed it does not cache anything.
I checked with chrome dev tools closed and indeed everything is neatly cached. I checked with a proxy running in the background and no new requests were made, so no flashes of your header image


1 Like

Not sorry to revive an old thread, but I heard something from a commenter on stack overflow that sounded relevant and I think it may be for you too. They asserted that the problem was better shown on a slow connection and when I activated network throttling (at least chrome supports this in the dev tools if you choose “response device mode”) and I can now see what you’re seeing.

What helped the other person was setting different caching headers on those files - then at least subsequent loads came from cache for your visitors (who aren’t running cacheless to debug things :slight_smile: )

Normally we advise against changing your caching settings but in this case it may make sense for e.g. that file, AS LONG AS YOU ARE SURE IT WON’T CHANGE! That’s the major problem with changing cache settings: “oh, I’ll let it last a year.” <6 months pass> “oops, we got acquired, need to put a new logo in place but…oh, the old one is stuck in browser cache for another year for people who visited yesterday”.

So - I couldn’t quantify exactly where the problem was in my test, but it seems like you’ve quantified that, so I’d suggest posting your proposed header rules here so we can review them and make sure they are specific enough not to cause problems like that in the future. In fact I’d try it just on that header image to start with, so maybe that’s just this for your _headers file:

   Cache-Control:  max-age=172800

Would be a good starting test. If it works well you could expand it to e.g. all /static/images/* files with the caveat that you’d want a NEW NAME for any files (such as splash.jpg) that you need to change later. That’s just a 2 day test but you can of course stretch it out as long as you feel comfortable once you’ve seen whether it makes an improvement.

Note that you CAN test headers like that in a deploy preview BEFORE going to production so very much recommended :slight_smile: