渲染:收集包装每个项目?

时间:2011-06-01 04:30:44

标签: ruby-on-rails

目前我正在使用:

<% @items.each do |item| %>
  <li class="list-item">
    <%= render :partial => '/widgets/vertical_widget',
               :object => item %>
  </li>
<% end %>

在页面上渲染大约20个项目(在同一页面上还有另外20个不同的小部件)。

当我查看我的服务器日志时,每个小部件渲染显示约400毫秒,页面总计约为20毫秒。从我读过的内容:集合而不是循环:对象应该有助于改善那些时间,但是如果我使用:集合,我不知道如何在LI中包装小部件的每个实例。从来没有在网站上使用的小部件位于列表中,因此在小部件代码中包含LI是没有意义的。

我可以直接在窗口中包含窗口小部件代码而不是部分代码但是我不想在多个位置进行代码更新。

任何其他改善表现的想法都会受到赞赏!

2 个答案:

答案 0 :(得分:4)

尝试content_tag

#some_file.html.erb

<ul>
<%= render :partial => 'widgets/vertical_widget', 
           :collection => @items, 
           :locals => { :wrap_in => :li } %>
</ul>



#/widgets/vertical_widget.html.erb

#First, render and capture the content once.
<% @rendered_content = capture do %>
  #render the item here
<% end %>

#Next, decide if the content rendered above should be wrapped in a tag or not
#If the "wrap_in" variable was passed-in and it is not nil/empty, then use that
#value for the tag; else do not wrap the content in a tag
<% if defined?(wrap_in) && !wrap_in.blank? %>
  <%= content_tag wrap_in do %>
    <%= @rendered_content %>
  <% end %>
<% else %>
    <%= @rendered_content %>
<% end %>

答案 1 :(得分:2)

我意识到这是一个迟到的答案,但对于有类似问题的人可能会有用。

Zabba的回答非常好,作为一般指导原则应该有所帮助。但是,您的缓慢问题可能与渲染无关。如果单个渲染需要400毫秒,那么很可能您在'vertical_widget'部分内重复访问数据库。检查日志以查找正在进行的查询,并查看是否可以使用本地变量缓存任何查询。