4

When navigating my site, my browser is loading the JS files from cache, but not the CSS files. This happens both running a local server and on the live site (to me and apparently to other users, which is apparent since the logs show mostly .css files getting loaded).

I've tried the other solutions (example): I am clicking around on hyperlinks (not refreshing) and my Chrome Devtools do not have "Disable Cache" checked.

Here is the initial request (using CTRL+F5 for a hard refresh):

enter image description here

Then navigating back to that page creates another request:

enter image description here

(Note: there is no Cache-Control sent in the second request, proving that I indeed did not refresh)

As expected, the server responds with a 304 Not-Modified for the .css file, but I don't understand why it's making a trip to the server at all (notice below the .js file is retrieved without a server request).

enter image description here

I believe you can look at the issue first-hand on your own machine by going to https://up.codes. I'm using Chrome 71.0.

Why are the CSS files not being cached?

15
  • I did not understand what is your yuestion and what you need? Nobody will answer you without this. Would you like to write it, please. Commented Jan 9, 2019 at 9:09
  • @Bharata, ok I've clarified the question at the bottom, thanks. Commented Jan 9, 2019 at 15:57
  • @Garrett I just checked your site and all your css files were cached just fine on my end. I also get status 304 - NOT MODIFIED for all of them after the first time I've downloaded them. Are you sure you don't have some kind of debug mode set on your end that's forcing all assets to be re-downloaded? I see that your request headers contain "Cache-Control: no-cache"... Commented Jan 9, 2019 at 21:17
  • @m_katsifarakis, thanks, I added a paragraph/image to clarify. It sounds like we have the same behavior. I also get a 304 back when hitting the server on the second request, but I don't want there to be a request at all. Commented Jan 9, 2019 at 22:53
  • @m_katsifarakis, the first request indeed has a "Cache-Control: no-cache" because I did a hard refresh (CTRL+F5) for the first one. I could have also just opened Incognito and navigated to the page for the first time ‒ on second request, the problem still manifests. Commented Jan 9, 2019 at 22:55

4 Answers 4

5

@Allen found the issue (Vary header included cookie and the cookie was changing between requests), but I'll show how to fix it for the case of Flask for posterity. You can use Flask's @app.after_request() hook to make sure Flask does not add cookie when it hits this line:

@app.after_request
def add_header(response):
    url = request.url
    if ('.css' in url or '.js' in url or '.svg' in url or '.png' in url or
        '.gif' in url) :
        # Flask adds to the header `Vary: cookie` meaning the client should 
        # re-download the asset if the cookie changed.  If you look at the Flask
        # source code that comes next after the below return, it will add 
        # `Vary: cookie` if and only if session.accessed is true.
        session.accessed = False
    return response
Sign up to request clarification or add additional context in comments.

2 Comments

you should use nginx as front server to handle these static files. docs.gunicorn.org/en/stable/deploy.html
@Allen - That's not mutually exclusive with this answer. In my case, I have nginx in front of the flask app configured as a caching, with specific application paths (/static, in my case) having a extremely long proxy_cache_timeout parameter. That way, you can just use the built-in server for testing, and the deployed version still gets the benefit of having a fast front-end.
1
+200

Your server responded with different session cookie when requesting these css files, and your header set with Vary: Cookie, which caused the browser to send request again because of the session cookie change.

1 Comment

Thanks, you are right! Indeed the .css requests had different cookies sent while the .js requests sent the same cookie. Not sure why that is, but it was an easy fix to modify the Vary header to not have Cookie in it which I show below for the case of Flask.
1

Check out for your web.config's compilation attribute, if its:

<compilation debug=”true”/> 

CSS will get continually downloaded by clients on each pageview request and not cached locally within the browser.

If its set to false, the resource is only downloaded once to the client and cached there.

Check out this post: Chrome will not cache CSS files. .js files work fine

1 Comment

Thanks for the answer! Unfortunately, I'm not using IIS as in the linked answer, but rather Flask (Python). But actually, I think this problem is independent of the server technology. There's an issue with my response header, with Chrome or with my understanding of how caching works.
1

Chrome uses multiple types of caches.

Blink (the rendering engine that Chrome uses) uses an in memory cache and a disk cache. It uses this cache for images, fonts and js files. As long as a file of that type is still in the memory cache or the file cache it will be loaded from there and skip the WebRequest API, this means that no call is made to the server.

I don't know exactly why css files are not being cached by Blink, but this is the reason why you see an HTTP request for css files and not for js ones.

Note, that if, for some reason, the js file is evicted from the memory cache and the disk cache you will see an HTTP request for the js files also.

1 Comment

Thanks, that's good to know, especially as a starting point for digging in to the Chromium source code if it comes to that. Strangely, ever other site seems to work fine (for example, Stack Overflow's CSS files say (from disk cache) in the "Size" column).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.