Force Browser Caching Across Browser Sessions - caching

I help maintain several Wordpress-based websites that publish news and reference information.
We have been working hard to make pages at the websites load as fast as possible.
One of the things we've done is implement very long "max-age" times in the "cache-control" http headers for most of our static files, such as images and css files.
The particular cache-control setting we're using is "public, max-age=31536000". 31,536,000 seconds is 365 days.
The upside is that this setting does, in fact, cause the static files to be cached as visitors browse through different pages of our sites.
But here's the rub. This cache-control setting doesn't do much for us across browser sessions. Even though the setting is supposed to tell the browser "cache this file for an entire year", if a visitor to our site shuts down their browser, then starts it up just five minutes later and comes back to our site, the browser insists on re-loading all the static files, even though it still has them in its cache.
I've checked this carefully in Firefox, viewing the headers with Live HTTP Headers. But I can also qualitatively see the same thing happening in other browsers.
Apparently, browsers insist on re-loading all content for a website if the content hasn't been loaded once during the current browser session.
So ... Is there any way we can "politely suggest" to browsers that they always load cached content from the cache, even if the browser hasn't been to our site during the current browser session?

Check the ETag, Expires, and Last-Modified headers as well.
You need an Expires header, and sometimes ETag and Last-Modified can defeat caching.

Related

Why YSlow is not detecting my cookie-free domains?

I have moved all my static assets to cloudfront.net, and when I view my source code, my CSS and JS and images are already hosted in cloudfront.net. But when I check GTmetrix.com, my use cookie-free domains is still graded F, and my main domain is still showed in the list, instead of cloudfront.
I already cleared my cache, cloudflare cache, browser cache, and all kinds of cache, but Yslow in GTmetrix still doesn't detect that I'm using a CDN (cloudfront.net).
Anyone here who encountered the same problem?
Actual GTMetrix Result:
https://gtmetrix.com/reports/www.flyskyjetair.com/SgHBKXsJ
Actual Code:
view-source:https://www.flyskyjetair.com/
If you have the strip cookies and cache cookies options enabled however when running your site through YSlow are still receiving a warning, this is due to a YSlow false-positive. If you set your cookies on the top-level domain (e.g. yourwebsite.com) all of your subdomains will also include the cookies that are set. This also includes your custom CDN URL if using one (e.g. cdn.yourwebsite.com).
However, as long as you have the strip cookies option enabled, even if you receive this warning it will be incorrect. YSlow does not take into consideration that the CDN actually strips the cookie and therefore may continue to throw the error. However, if you run a cURL command on the asset or check it within the Chrome Dev tools Network tab, you won’t see any Set-Cookie headers. Therefore this YSlow warning can be safely ignored.
If you are using Cloudflare then you simply won’t be able to achieve 100 on YSlow. Cloudflare appends a __cfduid cookie to every request which cannot be removed due to security reasons.

Firefox incorrectly caches AJAX calls in BFCache ignoring caching headers

We have a page that makes AJAX calls to get a JSON file. The JSON file has a 'max-age=60' header.
On Firefox, the JSON file is incorrectly cached by BFCache beyond the 60 seconds specified by caching header. What is worse is that force-reloading (Shift+F5) doesn't help, as the JSON file is not retrieved from the server anymore.
This is a bug in Firefox, opened one year ago and still unresolved: https://bugzilla.mozilla.org/show_bug.cgi?id=1055024
Answers to this question How to force Firefox to bypass BFCache for Angular.JS partials? mention some workarounds that involve clearing the full cache or installing extensions. We have millions of users and it's not practical for us to ask them all to go through these steps.
Also, setting a 'unload' event in the page seems to disable BFCache completely for the page. This is also not an optimum solution for us, because we would like the whole page to benefit from BFCache speedup, and still see fresh JSON content honoring the max-age=60 header.
Does anyone know if there are specific caching headers that will hint BFCache NOT to keep this particular file and fetch it from the server once the max-age period has elapsed?

Browser caching of static resources (js, css): is it a real problem?

I wonder whether caching static resources by browsers (pretty much fresh: IE8, FF 3.6) is a real problem of development web application (when from time to time fresh version of webapp is going live and development continues).
Taking into account that serving static content by server is correct in terms of appropriate headers (last-modified, etags and etc.) and response codes (304 when not modified and 200 with body when changes exist).
Can be there any situations when serving html is fresh, while static still taken from browser cache?
Unless you provide an Expires header, the browser should check for a new version each time the content is loaded, so it shouldn't be a problem (assuming the server gives the correct response).
But to be absolutely sure, you can give each version of your javascript/css a different filename, and change the filename in the HTML when you update. Then when the browser loads the HTML it will have to load the correct resources.

How do different browsers handle caching for static content without an Expires Header?

After running the YSlow plugin on a site, I saw that one of the recommendations was to add far future expires headers to the scripts, stylesheets, and images.
I asked a different question about how to set this up in IIS, but I am actually just curious about how each browser behaves.
I have read that IE will cache items per browsing session, so once you reopen the site after closing the browser, it will need to reload all of the content. I believe that Firefox will go ahead and set a expiration date on its own. I have also heard that IE does not cache at all when connecting over HTTPS. I am not sure if these are at all accurate, though, and was wondering if someone could clear up any misconceptions I may have. Thanks!
You are right about Firefox setting its own expiration date. See the second item in this blog post:
http://blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/
IE, like Firefox, can cache HTTPS based content. However, you need to set Cache-Control: public for persistent caching across browser sessions in Firefox. See Tip #3 in this blog post:
http://blog.httpwatch.com/2009/01/15/https-performance-tuning/

IE6 and Caching

It seems that IE6 ignores any form of cache invalidation sent via http headers, I've tried setting Pragma to No Cache and setting Cache Expiration to the current time, yet in IE6, hitting back will always pull up a cached version of a page I am working on.
Is there a specific HTTP Header that IE6 does listen too?
Cache-Control: private, max-age=0 should fix it. From classic ASP this is done with Response.Expires=-1.
Keep in mind when testing that just because your server is serving pages with caching turned off doesn't mean that the browser will obey that when it has an old cached page that it was told was okay to cache. Clear the cache or use F5 to force that page to be reloaded.
Also, for those cases where the server is serving cached content it you can use Ctrl+F5 to signal the server not to serve it from cache.
You must be careful. If you are using AJAX via XMLHttpRequest (XHR), cache "recommendations" set in the header are not respected by ie6.
The fix is to use append a random number to the url queries used in AJAX requests. For example:
http://test.com?nonce=0123
A good generator for this is the UTC() function that returns a unique timestame for the user's browser... that is, unless they mess with their system clock.
Have you tried setting an ETag in the header? They're a pretty reliable way to indicate that content has changed w3c Spec & Wikipedia
Beyond that, a little more crude way is to append a random query string parameter to the request, such as the current unix timestamp. As I said, crude, but then IE6 is not the most subtle of beasts
see Question: Making sure a webpage is not cached, across all browsers. How to control web page caching, across all browsers? I think this should help out with your problem too.
Content with "Content-Encoding: gzip" Is Always Cached Although You Use "Cache-Control: no-cache"
http://support.microsoft.com/kb/321722
You could also disable gzip just for IE6
A little note: By experience I know that IE6 will load Javascript from cache even if forced to reload the page via Ctrl-F5. So if you are working on Javascript always empty the cache.
The IE web developer toolbar can help immensely with this. There's a button for clearing the cache.

Resources