Reputation: 8736
I do understand how Cache-Control
header works. However, I noticed that the browser treats the document request differently from other requests. The document request here is the first request that the browser makes when the user types the domain on the address bar and hits enter.
I tested an HTML page with the response header as follows:
Cache-Control: public, max-age=31536000, immutable
The header tells that the browser should cache the response for 1 year. But in the case document request, both Chrome and Firefox will revalidate it anyway. The evidence for it is the 304 response status.
Here is the test URL: https://test-http-cache-2exijs7pxj7x.runkit.sh/
I can not find an official document for this behavior. So it would be nice if someone could explain how the browser caches the document request and refers to an official document.
Thanks in advance!
The outcome mentioned above is the result of a soft reload (when the user hits the reload button or re-enters the same address). For navigation requests, the browser respects the Cache-Control and serves the response from the cache
Upvotes: 3
Views: 514
Reputation: 13650
According to the spec, the immutable
extension to the Cache-Control
header:
Clients SHOULD NOT issue a conditional request during the response’s freshness lifetime (e.g., upon a reload) unless explicitly overridden by the user (e.g., a force reload).
The immutable extension only applies during the freshness lifetime of the stored response. Stale responses SHOULD be revalidated as they normally would be in the absence of the immutable extension.
The freshness of a response is determined by its age, which in HTTP is the time elapsed since the response was generated. You can read more about how a cache calculates the age on MDN, but it is essentially the difference between when the object was stored by the cache and it's max-age
(or the value of an Expires
header), which in your case is one year, so any cache following the spec, should not attempt a conditional request to validate the stored object.
I have confirmed on my Ubuntu laptop using Chrome and Firefox that Firefox will not issue a conditional validation request upon caching the response, but Chrome will. If you inspect the Browser compatibility table on MDN for the Cache-Control
header, you will see that Chrome does not support the immutable
extension, but Firefox does.
In short, according to the spec, clients should not issue a conditional request to validate a cached object that included the immutable
extension to a response's Cache-Control
header while the object is still fresh.
Chrome is not honoring the immutable
extension, and therefore issuing a conditional request in the form of an If-None-Match
request header due to the Etag
on the returned resource.
Addendum:
The comments to this answer add an additional question not readily apparent in the original question. Namely, why is Chrome validating a cached resource that is fresh when a user reloads the page, but not during navigation?
Chrome has decided to not support immutable
because they seem to feel their heuristic at handling reloads is sufficient and not worth the overhead of supporting another extension to Cache-Control
with little observed value. It has been available to work on for years, but nobody has bothered.
In short, their heuristic will only validate a cached top level resource on reloads (which real end users really don't do), and use the cache for sub-resources. You can read about how Chrome revamped their heuristic in this article: https://blog.chromium.org/2017/01/reload-reloaded-faster-and-leaner-page_26.html
Note, the test URL provided in the question does not have any sub-resouces. Not only that, it appears to be serving plain text as text/html
where text/plain
might be more appropriate.
Upvotes: 3
Reputation: 1653
Your browser will still send a request to the server this is called a "conditional GET"
as you can see on the initial request there is a header on your request which is the "If-None-Match"
This header is used to perform conditional GET requests based on entity tags (ETags) assigned to the requested resource.
The browser sends the ETag it has for the resource, and if the resource on the server has the same ETag, the server responds with a 304 Not Modified status code. indicating that the browser should use its cached copy of the document. If the document has been modified, the server responds with the updated document.
This process is known as revalidation...
I was wondering if you expected something different from the browser?
even if your browser already has a cached-copy of the page, it will still need to check if the cached-copy it has is an updated one...
if you want to bypass the revalidation entirely then you can disable ETAG... (which is what I think is the main issue)
if it does still sends a revalidation request maybe do things like make sure that your response have a Last-Modified
and Expires
Headers (I think this is a fix, if still revalidating, maybe you can update the test site you have so I can do some more investigations)
I hope that helps...
Documentations that might help:
Upvotes: 0