I'm trying to optimize the loading time of a website. One of the things I've done is set a far-futures expires header for static content so that they are cached (as described by Yahoo). However, even though they are cached, the browser still sends a request and gets back a 304 (Not Modified) response for that resource.
I realize the 304 response is very small and probably has minimal performance effect, but is there a way to make it such that the browser will no longer send the request at all and just always use the cache for that resource?
You may want to try turning off ETags if you are sending both etags and expires. Some people suggest turning off eTags, especially if you have a load balancer.
Also, note, when you press reload on your page, Firefox WILL recheck all the resources. These will come back with 304's. If you press shift-reload, it will re-request all the resources without etags. So don't use the refresh/reload button to test your last-modifed/etag settings.
Related
I have a web server which returns 200 OK with a bunch of set-cookies, and an HTML page which loads a bunch of scripts from the same server.
However, the subsequent loads that was spawned from that HTML page submits a different cookie on their HTTP request headers.
What could be causing that? Surely there's some policy I'm missing out on, but I don't see why it works on some pages and not others?
I'm using chrome as the browser, but this behavior also happened from iOS, so I'm guessing it's not browser specific.
So after a lot more reading and troubleshooting, it turns out that when you don't set a cookie path, it'll default to whatever path the original request set-cookie was sent to. And because my resource paths had a different path, the cookie was not sent.
Adding Path=/ fixed it for my issue. Of course, if you don't want your cookie to be accessible to all pages this is bad, but my web-server requires requests to come with cookies because they are sensitive data (for security reasons).
I'm trying to implement cache control on my application. I've set up the tomcat filter for the all fonts giving a max-age=120.
When I request a font for the first time with the cache cleared, the call/response is the following:
and as you can see I have the max-age response. Now I expect that if I hit refresh the browser won't send the http request again instead this is what happens:
As you can see the second request has a
cache-control: max-age=0
value and the response is returned from the server cache. What I'm trying to achieve is to block the entire call from the browser.
Am I doing something wrong?
Thanks
Hitting refresh has semantics that are dependent upon the browser you're using, but often it will make a conditional request to make sure the user is seeing a fresh response (because they wanted to refresh).
If you want to check cache operation, try navigating to the page, rather than hitting refresh.
OTOH if you don't want refresh to behave like this -- and you really mean it -- Mozilla is prototyping Cache-Control: immutable to do this (but it's early days, and mob-only for the moment).
I know this question is asked for several times. But Still I am not clear about the concept. After reading many blogs and answers in SO what I got is,
Expiry headers are used when you don’t even want client (and proxies/caches) to make a request to
the server. In ETAG, the client will check with the server for the update, but in expiry
headers, the client will know, when to expire the file and check for an update, till then it
(browsers and proxies/caches) won’t bother server for checking the update.
So basically it say if we use expires/max-age header , It will not even check for the server for an updated file. So I thought to test it locally.
So I have created on simple html file including 2 js files and 1 image file. In IIS , I have set the Expires header to 2 days for the image folder. So as per my understanding , after getting the image file from the server once, for next request it should not send a request to the server to check the image file is modified or not.
But what I got is each time I refresh the page I see a request sent to the server and the server returns a 304 not modified status. But as per the specs/blogs I read It should not send a request to the server.
Someone please explain.
For what you have described
It is clear that ETag works as it expected to be by responding with 304 not modified for the request with If-None-Match field and ETag value.
so now the browser will load the image from cache instead of getting a new image from server costing bandwidth and time.
It seems that caching is disabled in your browser.That's why a new request has been sent before the cache expiration or else a request wouldn't have been sent in the first place.
Here is a wonderful article that explains how to find caching is disabled in browser programatically
Here is a another wonderful article that explains caching and Etag in depth.
Note:
Generally speaking
If you are using multiple servers with load balancer to host your website
then simple Etag configurations likely going to cost more bandwidth by having Etag in their header and it has no purpose which is checking if browser cache is valid.(Its always going to say invalid)
The important part is what you said: I refresh the page. In this case browser is trying provide you the fresh content so it has no other option than to contact server and check all resources. (There is cache control extension immutable which prevents this behaviour but is not widely used and implemented).
If you want to see behaviour of your browser which respects caches without reload you have to use "standard page entry". Either follow a link to the page or use another tab and write the page url to the url bar and press enter.
Caches respects expiration time so if document is not stale then is returned from the cache. If expired that ETag is used to validation of the resource (and after validation it is possible that resource is still not modified - 304 response)
I am working on a new API. With ETags enabled, Chrome always conditionally GETs a resource with a long cache lifetime, that is, Chrome no longer uses the cached version without first confirming the ETag.
Is this how ETags are supposed to work with GET?
If so, and considering that I don't need them for update race-checking, I will remove the ETags and alleviate the extra work my server is doing.
Edit
I would have expected Chrome to use the cached item according to the max-age until it expires and then use the conditional GET to update its cached-item.
As I write this, it has now occurred to me that it would not be able to 'update its cached-item' since the 304 contains no max-age to use to extend the expiry time.
So I guess with ETags enabled, a client will always conditionally GET unless there's a good reason to use the cached version, such as no network.
Thus, it appears that ETags harm server performance when no concurrency control is needed.
Edit
I think I've already guessed the answer (above) but here's the question in a nutshell:
When ETags are enabled and the Max-Age is far in the future, should User Agents always use conditional GET instead of using the previously cached, fresh response?
How you load your page in the browser might be relevant here:
If you press Ctrl and reload the page using the refresh button, that will cause an unconditional reload of your resources with 200s returned.
If you just reload using the refresh button (or equivalent key like F5), conditional requests will be sent and 304s will be returned for static resources.
If you press enter in the address box, add the page to your bookmarks and load from there, or visit the page from a hyperlink, the cache max-age should work as expected.
With ETags enabled, Chrome always conditionally GETs a resource with a long cache lifetime, [...] Is this how ETags are supposed to work with GET?
The answer is in the RFC:
10.3.5 304 Not Modified
If the client has performed a conditional GET request and access is
allowed, but the document has not been modified, the server SHOULD
respond with this status code.
So, yes.
If this is not the answer you expect, you might want to include some actual traffic in your question that shows the order of request-response pairs that you expect and that you actually get.
considering that I don't need them for update race-checking
If you're not going to use conditional requests (If-Match and the likes), you may indeed omit the ETag calculation and processing.
We have a web site that does not have a favourite icon favicon.
Therefore, we get a lot of http 404 errors for the file favicon.ico.
For the functionality of the web site it does not make a difference.
But I was wondering if the system uses more time looking for a file that is not there, rather than returning a 304 not modified?
At max load we have ca. 15,000 concurrent connections across all frontend servers.
No, the performance difference is insignificant - if you don't want to have a favicon, I'd suggest creating a 0-byte /favicon.ico : the logs will stop complaining, and the browsers will behave as if there's no favicon.
Also, you could set a far future Expires header for your favicon - that way, the clients will only request it once, further reducing the load.
In terms of the load the request causes on the server, there is no difference.
In terms of network bandwidth, a valid 304 response will be a bit bigger, since you also have to include at least a Date and an Expires or ETag headers in the response.
If the idea is to send a response without content, then I think 204 No Content is more appropriate.
If you are absolutely sure that the web site will never ever have a favicon, you could use a 410 Gone response. That tells the client/browser to don't come back and ask again. It is also more likely to be cached by a proxy server than a 404.