Move item_link partial caching to a helper rather than the template itself

This is a surprisingly huge performance gain. On my testing (with
cache_classes set to true to also cache templates), this sped up
closet_hangers#index rendering by a factor of 2 when there were a
significant number of items. Cool beans.

I think we can even hold off on the individual hanger caching now:
we've made the closet hanger partial tons faster by moving forms out
of them and doing this cache check earlier. I'm expecting significant
performance gains both here and on items#index (though less so there).
I'll deploy and see how much it helps in production; if not enough, we
can look at the layered caching of hangers, lists, groups, full pages,
etc.

So glad we don't *have* to move to a pagination model!
This commit is contained in:
Emi Matchu 2013-06-22 16:31:46 -07:00
parent d132567931
commit 816584f177
4 changed files with 23 additions and 7 deletions

View file

@ -120,6 +120,23 @@ module ItemsHelper
" (×#{count})".html_safe if count > 1 " (×#{count})".html_safe if count > 1
end end
def render_item_link(item)
# I've discovered that checking the cache *before* attempting to render the
# partial is significantly faster: moving the cache line out here instead
# of having it wrap the partial's content speeds up closet_hangers#index
# rendering time by about a factor of 2. It's uglier, but this call happens
# a lot, so the performance gain is definitely worth it. I'd be interested
# in a more legit partial caching abstraction, but, for now, this will do.
# Because this is a returned-string helper, but uses a buffer-output
# helper, we have to do some indirection. Fake that the render is in a
# template, then capture the resulting buffer output.
capture do
localized_cache("items/#{item.id}#item_link_partial") do
safe_concat render(partial: 'items/item_link', locals: {item: item})
end
end
end
private private
def build_on_pet_types(species, special_color=nil, &block) def build_on_pet_types(species, special_color=nil, &block)

View file

@ -1,4 +1,4 @@
%div{'class' => closet_hanger_partial_class(closet_hanger), 'data-item-id' => closet_hanger.item_id, 'data-quantity' => closet_hanger.quantity, 'data-id' => closet_hanger.id} %div{'class' => closet_hanger_partial_class(closet_hanger), 'data-item-id' => closet_hanger.item_id, 'data-quantity' => closet_hanger.quantity, 'data-id' => closet_hanger.id}
= render :partial => 'items/item_link', :locals => {:item => closet_hanger.item} = render_item_link(closet_hanger.item)
.quantity{:class => "quantity-#{closet_hanger.quantity}"} .quantity{:class => "quantity-#{closet_hanger.quantity}"}
%span= closet_hanger.quantity %span= closet_hanger.quantity

View file

@ -1,3 +1,3 @@
.object .object
= render :partial => 'items/item_link', :locals => {:item => item} = render_item_link(item)
= closeted_icons_for(item) = closeted_icons_for(item)

View file

@ -1,5 +1,4 @@
- localized_cache "items/#{item.id}#item_link_partial" do = link_to item_path(item) do
= link_to item_path(item) do
= image_tag item.thumbnail_url, :alt => item.description, :title => item.description = image_tag item.thumbnail_url, :alt => item.description, :title => item.description
%span.name= item.name %span.name= item.name
= nc_icon_for(item) = nc_icon_for(item)