I used Chrome's auditing feature to try to find some performance bottlenecks in my web site. I found a lot of reports of non-cacheable resources.
I did a dry run with a single-page containing a stylesheet in a library and found the same thing:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html" >
<h:head>
<h:outputStylesheet library="default" name="style.css"/>
</h:head>
<h:body>
<div><h:outputText value="test"/></div>
</h:body>
</html>
Here's the audit log entry:
The following resources are explicitly non-cacheable. Consider making them cacheable if possible:
style.css.jsf
The interesting thing is, if I remove it from the library, this message goes away. So, it looks like there is a problem with caching resources in libraries.
Is there a way to fix this?
EDIT: According to one of the comments in this answer, perhaps CSS is not cached if a normal refresh is performed on the page: Set HTTP headers properly to force caching on JS, CSS and PNG files
Can that be right? Why can't a bookmark or typed in URL re-used the cached copy?
This is a false error.
The library
attribute adds the library value as a query string, see also What is the JSF resource library for and how should it be used? Chrome Audit appears to penalize any query string in the resource URL, even though the response headers and actual browser behavior during refreshs are completely valid. I just tried on my own Chrome and I can indeed see this false error too.
If you tab back to "Network" tab, then you must notice valid Expires
, ETag
and Last-Mofidied
response headers (and no Cache-Control
) and you must observe the below browser behavior:
If those resources were really "explicitly non-cacheable" as literally mentioned by Chrome Audit, you'd have seen a full HTTP 200 response in each single case.
Query strings in resource URLs are often used as cache busting technique. When a resource is updated in server side, then the developer of course want to force a fresh reload in client side. One way is renaming the resource path/filename, but another and more common way is changing a query string parameter value (usually, the one representing a version or timestamp).
Try a more decent web performance testing tool. E.g. YSlow. In my case, it didn't flip on query strings in resource URLs.