I started working with Spree almost 5 weeks ago and let me tell you that at first I was scared. That because I didn't know much about it, but the trick was to lose your fear and go deeper into Spree code to learn as much as you can. With that said, let me share some little tweaks that helped me to increase the performance of the store I was working on.
Override taxonomies partial (if you don't need it)
I needed to increase performance in the main product list, to be more specific Spree::TaxonsController#show
, it was taking so much time to get the products so I installed New Relic's gem to see what was going on and I found this:
<nav id="taxonomies" class="sidebar-item" data-hook>
<% @taxonomies.each do |taxonomy| %>
<% cache taxonomy do %>
<h6 class='taxonomy-root'><%= Spree.t(:shop_by_taxonomy, :taxonomy => taxonomy.name) %></h6>
<%= taxons_tree(taxonomy.root, @taxon, Spree::Config[:max_level_in_taxons_menu] || 1) %>
<% end %>
<% end %>
</nav>
The code above represents the _taxonomies.html.erb
partial that is rendered inside the taxons#show
template. Spree uses this partial to allow the user to shop by taxons and it was making a lot of queries that looked like this:
SELECT "spree_taxons".* FROM "spree_taxons" WHERE ("spree_taxons"."lft" <= 2) AND ("spree_taxons"."rgt" >= 45) ORDER BY "lft"
You'll say, well, it's actually cool to let the user shop by taxons. Indeed, it is. But the store I was working on had lots and lots of taxons and we already had a menu for some of them, that's why I decided to override Spree's partial and bang! the request time went from 8000ms
to only 3000ms
. That is still a lot, but it's way much better.
Use multi fetch fragments gem
This gem gave me an incredible boost when rendering the products collection. All you have to do is to have the dalli gem installed for cache or another Ruby memcached client that supports multi-get. After you install the gem, you would just need to render the collection as usual and pass the cache: true
option, at the end you'll end up with the following.
<%= render @products, cache: true %>
and that'll be it, in my case the request went from 3000ms
to 500ms
.
I hope these two little tips are useful for you. I'll try to find some other tricks to improve performance. In the meantime, I just have these two but I'm sure that if you've been working with Spree before, you'll probably have some other tips that I would like to hear about down in the comments.
Thanks for reading.