Cache your partials, not the other way around.
It might seem nice and tidy to do this:
# items/index.json.jbuilder json.items @items do json.partial! "item", item: item end # items/show.json.jbuilder json.item do json.partial! "item", item: @item end # items/_items.json.jbuilder json.cache! item do json(item, :id, :name, ...) end
The templates are DRY and things are organized.
But tucking the call to cache! into the _item partial is a performance hit. Consider:
# items/index.json.jbuilder json.items @items do json.cache! item do json.partial! "item", item: item end end # items/show.json.jbuilder json.item do json.cache! item do json.partial! "item", item: @item end end # items/_items.json.jbuilder json(item, :id, :name, ...)
While slightly more repetitive, this structure saves the calls to partial! once the cache is warm. Loading a partial isn't free, and the time it takes to load one up adds up when aggregated over x items per request, and y requests per minute.
Written by Kamil Tusznio
Caching with Rails 3.2
HTTP Posts in Ruby
Add your response
I'd love your feedback on this: https://github.com/joshblour/jbuilder_cache_multi
it uses fetch_multi in rails 4 to read all keys at once from the cache.
At first I was doing it the first way you described, then the second way, then I wrote this plugin to make it even faster.
Hey, that seems like a nice approach! Does it work with Rails 3?
It does! The thing is that Rails 3 doesn't give you a fetch_multi method, so it's up to whichever cache you are using to implement it. If the method doesn't exist, the gem will fall back on iterating over the collection (the second way you describe) so it becomes more of a convenience method than anything else :)
Thanks for pointing this out. I think the
|item| block parameter is missing in your examples though.