I have a loop that renders a partial
1000.times do |i|
render partial: 'test', locals: {i: i}
end
this is really slow, up to 0.1 ms for foreach render call, even if the partial only prints out i
my_partial = render_to_method(partial: 'test')
1000.times do |i|
my_partial(locals: {i: i})
end
Now this should be doing the same thing way faster right? But I don't know how to do this.
update:
I've tried the to do it this way:
Haml::Engine.new(File.read(File.expand_path File.dirname(FILE)+"/../table/#{column.macro}/_#{column.display_type}.haml"))
.render(OpenStruct.new({column_value: column_value, object: object}))
two major drawbacks:
update 2:
Many of the answers try to solve the problem by using other techniques. I my real application this techniques can't be applied. https://github.com/antpaw/bhf/blob/master/app/views/bhf/pages/_platform.haml#L54 mainly because this line is a dynamic string that sometimes links to partials that don't even exsist in the gem and are defined in the main_app. I wonder why it's so hard to do something that is so basic: 1. grab the view. 2. render it. (3. render it again.)
update 3:
@Flash Gordon suggested this https://gist.github.com/antpaw/d6670c23d6f08e35812e#file-gistfile1-haml-L54
template = lookup_context.find_template "#{column.macro}/#{column.display_type}", ['bhf/table'], true
template.render(self, {column_value: column_value, object: object})
it almost works just having some troubles with locals
. But it already feels like the part where you grab the template and the render part is well separated.
Here is an example from one of my previous answers. It's extracted from PartialRenderer
sources.
- local_names = [:i]
- partials = {}
- 1000.times do |i|
- name = 'name_%s' % (i % 10)
- partials[name] ||= lookup_context.find_template(name, lookup_context.prefixes, true, local_names)
= partials[name].render(self, i: i)
I'd recommend you to wrap it with a helper method. Keep in mind that locals' names appear here twice: first in local_names
as an array and second in hash's keys passed as the second argument of #render
method.