Marvin Danig
Marvin Danig

Reputation: 3908

How to speed up rendering of a rails_partial with form elements?

I have rails action that includes the following HAML partial:

- @items.each_with_index do |item, i|
  - item_no = 'item' + item.item_no.to_s
  .item
    = form_for item, remote: true, html: { multipart: true, autocomplete: 'off' } do |f|
      = f.hidden_field :parent_id, :value => @parent.id
      = f.hidden_field :image, value: item.image
      ...
      ...
      // 5-6 attributes

    - if @parent.has_item_numbers?
      .serial-number{ class: ('right' if item.item_no.odd?)  }
        = item.item_no

Number of items associated with its parent can vary greatly and can go up to 2000-3000 as well depending on user. We don't have limit on the number of children the parent can have yet. Before I can decide a limit:, is there a way to speedup rendering off .each_with_index method because right now this is taking up to 10 seconds to complete a request on my local.

There is some discussion of converting a partial to a method/block for speed but I don't understand it fully.

Also, of note is that this same partial was performing much better in rails 5.0.4 but it has slowed down considerably with rails 5.1.4.

Upvotes: 1

Views: 336

Answers (1)

user229044
user229044

Reputation: 239311

You should generally not iterate in your views. Instead, you should use collection rendering which will perform the iteration for you, and is known to be faster in addition to allowing you to implement fragment caching:

Your view:

= render @items, parent: @parent

Your partial (ie _item.html.haml):

- item_no = 'item' + item.item_no.to_s
.item
  = form_for item, remote: true, html: { multipart: true, autocomplete: 'off' } do |f|
    = f.hidden_field :parent_id, :value => @parent.id
    = f.hidden_field :image, value: item.image
    ...
    ...
    // 5-6 attributes

  - if parent.has_item_numbers?
    .serial-number{ class: ('right' if item.item_no.odd?)  }
      = item.item_no

Upvotes: 1

Related Questions