https://dev.firmafon.dk/blog/rails-5-much-faster-collection-rendering/
Rails 5 将会带来更快的 collection render fragment (有 cache 的). Pull Request 已经合并了:https://github.com/rails/rails/pull/18948
原理是内部用了 Cache multi read,能有效减少 Cache 服务的连接,从而加快速度。
<%= render partial: 'item', collection: @items, cache: true %>
或者
<%= render partial: 'item', collection: @items, cache: Proc.new{|item| [item, 'show']} %>
在 Rails 5 发布前,大家可以用 multi_fetch_fragments。 已经在 Ruby China 上面用上,并刚刚上线了哦。
https://github.com/ruby-china/ruby-china/commit/dde8d199292571f9dd262c62b1495d58f2374214
题外话
Rails 允许 render 的时候使用 :collection 参数,这样也能有效减少耗时哦!
Before
<% @replies.each do |reply| %>
<%= render partial: 'reply', reply: reply %>
<% end %>
After:
<%= render partial: 'reply', collection: @replies %>
在这类有 partial cache 的情况下,故意 N+1 能有效减少查询开销哦。 比如 Ruby China 回帖这种情况,以前我们为了避免 N+1,所以会用 includes 方法
Controller:
def show
@replies = @topic.replies.includes(:user)
end
View:
<%= render partial: 'reply', collection: @replies, cache: true %>
但由于页面绝大大多数下,由于 Cache 存在,已经不再需要 user
对象了,所以去掉 includes(:user)
能少掉查询用户的动作。
参考这个 Commit 7793d342bab3069221cd9cba610d0b8c864332e3
实际效果,两个动作一起处理,Ruby China 话题列表从 上一次优化 的 60ms 左右缩短到了 42ms 左右了。