
Comparison of AngularJS cache vs. browser HTTP cache
When working with Angular's $http service, one of the nifty options is a built-in cache service. It's off by default, and enabling this service can prevent repeated requests for the same resource. In this post, I'll compare Angular's service to native HTTP caching in your browser (I used Chrome as a baseline for comparison, and other browsers may differ slightly).
Angular $cacheFactory | Browser HTTP cache (Chrome) | |
---|---|---|
Storage | Javascript heap memory (more) | disk (more) |
Eviction algorithm | Least recently used (LRU) | LRU (more) |
Time-to-live | until page refresh | Determined by HTTP headers |
Support for revalidation | No | Yes, with ETags |
Requires cooperation of remote server | No | Yes |
Example |
$http({ method: 'GET', cache: true, url: 'http://date.jsontest.com/ '}) |
Cache-Control: max-age=1800, private Vary: Cookie Content-Type: application/json ... |
Overall, I'd say the browser has the advantage, but there are many gotchas to look out for with HTTP:
- First, the server must be coorperating by sending suitable headers (usually easy if you control the remote resource, rare for third-parties).
- If your resources require authenication, you'll need to set the
Vary:
header, andCache-control: private
. In the above example cookies are used, but other methods will work. For example if you authenticate with OAuth 2.0, the header would beVary: Authorization
. - Be careful with proxies, for example Varnish does not support "private" by default.
- When using HTTPS, Chrome and Safari will not cache resources from servers with self-signed certificates. This sometimes makes testing more complicated.
- Safari's implementation of
Vary:
is broken for cookies, and possibly other headers.
angular-cache
There is a third option if you can't solve the gotchas above, but need more flexibility: angular-cache. By using this replacement for $cacheFactory
, you get more storage options (localStorage and sessionStorage), and a configurable time-to-live.
Comments
I was interested to read the comparison but most of the table wasn't visible in the mobile theme on the iPhone.
Mon, 03/24/2014 - 07:34
Thanks Andrew, we'll take a look at it.
Thu, 07/24/2014 - 21:06
Thanks for the informative post!
We're developing an app with AngularJS and RESTful services. The data returned by services is changed infrequently and I very much would like to cache responses for a period of time. I'm setting Cache-Control: no-transform, max-age=604800
in the response.
Is there a way to have AngularJS JSON requests ($http/$resource) respect browser cache instead of using completely parallel built-in AngularJS cache or angular-cache library? From what I can see watching the network, by default $http requests are ignoring Cache-Control headers.
Cross-posted on StackOverflow: http://stackoverflow.com/questions/24943922/is-there-a-way-to-use-brows…
Fri, 07/25/2014 - 00:28
Yes, in our testing $http definitely honors cache-control headers. I'm not sure AngularJS could opt-out of browser caching, even if it wanted to, since under the hood it must use XMLHttpRequest().
As noted above, an invalid SSL cert will prevent caching. If that doesn't explain what you see, perhaps you could share a link to a sample endpoint URL? If there are other conditions that interfere with browser caching I'd love to know about it. Thanks!
Fri, 07/25/2014 - 00:55
Thu, 11/03/2016 - 16:13
is there a way to clear all caches in $cacheFactory at once.
Mon, 01/09/2017 - 18:41
As far as I understand there is no existing method that allows to do that in one call.
But you can use $cacheFatory's info() method to get list of all created cache objects and then call removeAll() method on every cache object.
Sun, 03/23/2014 - 15:07