将partial转换为method/block以获得速度

ant*_*paw 4 ruby performance ruby-on-rails partial ruby-on-rails-4

我有一个循环,呈现部分

1000.times do |i|
  render partial: 'test', locals: {i: i}
end
Run Code Online (Sandbox Code Playgroud)

对于foreach渲染调用,这非常慢,最长可达0.1 ms,即使部分仅打印出来也是如此 i

my_partial = render_to_method(partial: 'test')
1000.times do |i|
  my_partial(locals: {i: i})
end
Run Code Online (Sandbox Code Playgroud)

现在这应该以更快的方式做同样的事情吧?但我不知道该怎么做.

更新:

我试过这样做:

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})) 
Run Code Online (Sandbox Code Playgroud)

两个主要缺点:

  • 视图的路径不会像使用渲染时那样观察回退(parital:'partial'将在当前视图dir,某些宝石以及视图/应用程序中查找parital.
  • Rails视图助手不再可用

更新2:

许多答案试图通过使用其他技术来解决问题.我的真实应用这种技术无法应用.https://github.com/antpaw/bhf/blob/master/app/views/bhf/pages/_platform.haml#L54主要是因为这一行是动态字符串,有时会链接到甚至不存在的部分在gem中并在main_app中定义.我想知道为什么做一些如此基本的事情是如此困难:1.抓住观点.2.渲染它.(3.再次渲染.)

更新3:

@Flash Gordon建议这个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})
Run Code Online (Sandbox Code Playgroud)

它几乎可以解决一些麻烦locals.但它已经感觉就像你抓住模板的部分,渲染部分是完全分开的.

bbo*_*ozo 5

我喜欢这个问题,但它可能是"工作的错误工具"

基本上:

  1. 如果部分是简单的 - 考虑不使用部分,开销是不值得的
  2. 如果部分是复杂的 - 那么渲染1000个事物将花费时间,其中部分开销只是一小部分,你需要一个计划B

B计划:

  1. 最初渲染25-50-100 ....用户滚动时从服务器获取其他记录 - http://railscasts.com/episodes/114-endless-page
  2. 从服务器发送一个JSON数组,让客户端JS遍历集合并呈现HTML - 这样部分模板仍然可以在rails中呈现,客户端JS可以做 gsub
  3. 尽可能地缓存所有内容 - 这不包括不幸的形式,这通常是最慢的渲染组件
  4. ...

PS你试过细胞吗?https://github.com/apotonick/cells


Nik*_*kov 2

这是我之前的一个答案中的一个例子。它是从PartialRenderer来源中提取的。

- 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)
Run Code Online (Sandbox Code Playgroud)

我建议您用辅助方法包装它。请记住,当地人的名字在这里出现两次:第一次local_names作为数组出现,第二次出现在作为#render方法的第二个参数传递的哈希键中。