Search code examples
cssjsfgoogle-chrome-devtoolshttp-caching

Google Chrome Audit says "The following resources are explicitly non-cacheable" on JSF resources from library


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?


Solution

  • 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:

    • On a fresh request in empty cache, or on hard reloading the page via Ctrl+F5, you must see a HTTP status of 200 on those resources.
    • On navigating to another page referencing exactly same resources, or on clicking exactly same (bookmark) link again, or on pressing Enter in browser's address bar once again, you must see a grayed out HTTP status of 200 and a "from cache" in size column.
    • On reloading the page via F5 or Ctrl+R, you must see a HTTP status of 304 on those resources (and the browser will receive a much smaller response — only the response headers, no body — and continue using the cached version).

    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.