Reputation: 48827
I'm using Spring MVC 4, and handle static resources as follow (cache for one year):
<mvc:resources mapping="/static/**" location="/static/" cache-period="31556926" />
I have an app.js
file in my static
folder. When launching an audit with the Chrome DevTools, the app.js
file appears in the following section:
The following resources are explicitly non-cacheable. Consider making them cacheable if possible: app.js
The response headers for this static file request are:
Date: Mon, 23 Feb 2015 18:02:49 GMT
Expires: Tue, 23 Feb 2016 23:51:36 GMT
Cache-Control: max-age=31556926, must-revalidate
Are my static resources well cached by browsers? Why is the Chrome DevTools telling me that app.js
is explicitly non-cacheable?
Upvotes: 1
Views: 1068
Reputation: 49085
I have seen similar oddities with chrome audit and it seems the consensus is that Chrome audit might be buggy:
Google Chrome audit on caching
Besides the other answers in that referenced question I have two additional theories that I haven't tested thoroughly but I think might cause the issue:
1) Cookies
When you have cookies being passed along with the image which happens quite frequently with Java applications (jsession and various other cookies perhaps set in filters). The problem is that you didn't seem to show us any cookies in your header. Also newer versions of chrome audit typically complain about this as a separate error.
2) Dynamically requesting content via DOM change
Some Javascript library particularly ACE edit will dynamically add fonts and or Javascript (aka AMD) and occasionally add query parameters to the URL. This seems to confuse chrome audit. So perhaps your app.js
is being added dynamically through some other Javascript (ie adding a <script...src= ></script>
element) and/or adding query parameters to the URL?
UPDATE
I think I know what your particular issues is. Chrome audit does not like must-revalidate
and unfortunately when you specify a cache-period
greater than 0
the Spring ResourceHttpRequestHandler
will always add the must-revalidate
to the cache control header. If you don't set cache-period
(it will be -1) then Spring will still do caching headers but will not do must-revalidate
(however no max-age
leads to another audit error message of The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:).
Unfortunately you will either need to write a filter to remove the must-revalidate
or create your own version of ResourceHttpRequestHandler
probably extending and overriding cacheForSeconds
.
Some other options are to use an asset pipeline library like Wro4J or uploading the app.js to your CDN.
Upvotes: 1