Closed mikemaccana closed 9 years ago
Good question, but sadly, no. The way that static-asset works is by looking at req.url
and determining if that request already has a fingerprint. Therefore, the users' web browsers (or user agent) needs to know the URL for the asset in advance.
For example, /images/button.jpg
. If the user issues a request to /images/button.jpg
, then the resource is served without caching. However, you need the request to be something like /images/button.jpg?v=89df8d8af
Then, you can send special caching headers to the browser so that the browser will never request that image again. And, finally, if you happen to change /images/button.jpg
in the future, the browser will know to GET /images/button.jpg?v=34829fda
, which is technically a different asset.
So, in short, your templates need to know the fingerprinted URL, so that the rendered HTML contains <img>
tags that point to fingerprinted URLs.
You can do a couple things to work around this:
Anyway, hope that helps. I'd recommend this article for more info: https://developers.google.com/speed/docs/best-practices/caching
Thanks for answering Blake! I understand what you're saying, but what if:
Would that work?
This defeats the purpose of strong caching, which is to tell the browser not to bother with an HTTP request at all for a given resource. If a GET request for /images/button.jpg results in a 302, then the browser will still continue to request /images/button.jpg. Granted, if the 302 request points to a strongly cached resource, the browser won't bother with an HTTP request for it directly, but... now you essentially have 2 HTTP requests for a resource when it's not in the cache and 1 request when it's in the cache. What we want is 1 HTTP request for a resource, at most and 0 requests if we can help it. Most of the usefulness of node-static-asset is that it provides view templates with the URL fingerprint of a resource so that strong caching headers can be used, allowing browsers and other user agents to cache resources (for up to 1 year) without issuing another HTTP request. When you think about, that can save your server a considerable amount of bandwidth. Even an HTTP request that responds with 304 is fairly expensive (at a large scale), as HTTP is a rather verbose protocol.
But yeah, let me know if you have any other questions on this. Thanks!
Sorry for bothering you, but this isn't quite right:
If a GET request for /images/button.jpg results in a 302, then the browser will still continue to request /images/button.jpg.
The browser would request the URL given in the 302, not the original URL.
Granted, if the 302 request points to a strongly cached resource
Exactly, doing so was my suggestion. But acknowledged re: amount of HTTP requests, and thanks for answering.
Just to clarify...
If a GET request for /images/button.jpg results in a 302, then the browser will still continue to request /images/button.jpg.
What I was trying to say was... the HTML would contain the URL /images/button.jpg
, so the browser would issue a GET request for /images/button.jpg
. The server responds to this request with 302 and the fingerprint URL. Then, the browser would request /images/button.jpg?v=38d89f8a
, for example. That's 2 HTTP requests. If the browser needs to GET /images/button.jpg
again, it would again hit the server with an HTTP request, which responds with 302 again. If the asset hasn't changed, the server returns /images/button.jpg?v=38d89f8a
again. In this case, the browser knows that it doesn't need to issue another HTTP request.
Thanks Blake!
Sorry if the answer's obvious, but I wasn't sure from reading the docs.
Eg, all my images are underneath
/images
. I'd like to fingerprint all of them, without having to rewrite all my templates to use the view helpers.Would making all non-fingerprinted URLs redirect to the fingerprinted version work?
Thanks!