Google PageSpeed Insights Leverage Browser Caching Issue

I am testing the page speed of my django web app, hosted on pythonanywhere, using the google insights pagespeed tool. Whatever I do, Google always suggests as potential optimization to "leverage browser caching" and tells me that I haven't specified expiration date for my static files. I believe I read most forum topics on how to fix this but I insights always keep suggesting the same optimization over and over. I tried wrapping the application with whitenoise, setting up file caching, using the various decorators (cache_control, cache_page etc. ), using patch_headers_response, patch_cache_control etc. The only methods I haven't tried are those that require modifying nginx file, which is not available in pythonanywhere and .htaccess which is also unavailable. Has anyone had any success with this? Or is this something that always pops up with apps hosted on pythonanywhere? Thanks

Have you set up the static files using the "Static files" table inside the "Web" page? More information here.

I used the full path to the static folder for images and css/js. Do you mean I should use the {% load static %} variable and include the path as "{% static '/.../../file.css' %}" ? (I didn't think it makes any difference)

Did you read the link giles provided?

Thank you Giles and Conrad, I did read the link that Giles provided and didn't have success so far. Here are some of the steps I took

  • I set up a STATIC_ROOT path
  • I successfully ran python collectstaticfiles
  • In my Web tab I set up a path to my static folder
  • I used the static variable to load the path to my static files in my templates
  • I used a file based cache in my settings and experimented with the various decorators (cache_control (max_age=3000, public=True), cache_page(...)) as well as the functions patch_headers_response and patch_cache_control

So far I wasn't able to get google page insights to remove the recommendation to "leverage browser caching". I keep getting the same recommendation

Leverage browser caching for the following cacheable resources: (expiration not specified) (more files below this line)

Of course it could be that Google's tools is not 100% correct and that the browsers are caching the static files (someone else suggested this to me). But I am concerned that my webapp might be getting penalized from a SEO perspective ...

Hmm, OK -- I see what you mean. I think that Google's suggestion is debatable -- I don't personally agree with it, but I can see the argument they're making and it's not an unreasonable one.

Basically, the setup you have right now is that when a browser fetches a static page for your site, the response will have a "last-modified" time, which our server will have taken from the file timestamp. The file's content and that last-modified time will be put into the cache. When a browser requests the same URL again, it will send a "don't bother if it hasn't been modified since time X", where X is of course the cached last-modified time. If the file has not been modified, our server will respond with a short "nope, it's unchanged" response, so not much data will be transmitted -- it will be a quick response to the browser. If the file has been modified, it will send back the new file contents plus a new "last modified" timestamp, so it will be slower, but that doesn't matter because the browser really needs the new data.

This means that static files are pretty quick -- they're only sent in full if they have been changed. But it does mean that there's always a request for each file, and even a short "not changed" response requires a browser-to-server round-trip.

What they're recommending is an "expiration date" header. This can be helpful, but it can also cause problems. When you send a header like that, the browser is allowed to continue using its cached version and not even check with the server to see if it has changed. So if your static files don't change often, things can be quite a lot faster -- it skips the "has this file changed?" round-trip until the file expires from the cache. However, if they do change from time to time, it can mean that people browsing your site wind up using the cached version -- so, for example, if you change your main (uncached) page to look different, and as part of that update the CSS, you can wind up in a situation where people are seeing the new content with the old CSS, and it all renders weirdly.

You can work around that by changing your CSS filename every time you update it, and there are tools to help automate this (eg. by automatically using a hash of the file contents of the file contents as its filename), but it can get complicated quite quickly.

Our setup right now is designed to go for the former, "always get the browser to check" system because it's generally (in our opinion) the best way to do things, especially if you're actively developing the site. But perhaps we need to add something to allow people with sites that don't change that often, or who are willing to change filenames for static files in one way or another to force the second model.