Rails 中的分析视图

Posted

技术标签:

【中文标题】Rails 中的分析视图【英文标题】:Profiling view in Rails 【发布时间】:2011-02-14 07:27:52 【问题描述】:

我有一个大视图,需要很长时间才能完成渲染内容。最好的剖析方法是什么,视图的哪个部分花费的时间最多?我已经阅读了有关 ruby​​-prof 的信息,但我不确定在哪里放置它来分析视图渲染。如果存在其他选项,我也想知道它们。

【问题讨论】:

日志告诉我们渲染每个部分需要多少时间。您可以拆分视图进行检查。 【参考方案1】:

快速解决瓶颈的最简单方法是使用本地工作的 NewRelics 开发者模式。

    确保您的 Gemfile 中有 ruby-profnewrelic_rpm。 导航到localhost:3000/newrelic 并开始分析(在右侧栏中) 向您要分析的应用页面发出实际请求,可能会多次请求以确保您不会测量某些缓存和内容。 导航回 newrelic 开发者模式,选择请求跟踪。 按“self”列对表进行排序。这一点至关重要,因为默认按总时间排序会产生误导。 查看前 10 个调用,它们是如何调用的,您可能会发现瓶颈。

免责声明:我已经将这个排序功能推到了newrelic的开发者模式,所以我有偏见。不过自己试试吧。

【讨论】:

不知道出了什么问题,但localhost:3000/newrelic 在我今天使用的版本中不再可用,即newrelic_rpm 4.8.0.341 “从 Ruby 代理版本 4.1.0 开始,开发者模式已被删除,不再受支持。” docs.newrelic.com/docs/agents/ruby-agent/features/…对不起。【参考方案2】:

其实很简单。我刚刚发现并修复了使用 ruby-prof 的 HAML 模板的性能问题。模板的相关部分如下所示:

  - @collection.each do |x|
    = render :partial => 'name', :locals => :object => x

我确定 ruby-prof 在 Gemfile 中并暂时将其更改为:

  - require 'ruby-prof'
  - RubyProf.start
  - @collection.each do |x|
    = render :partial => 'name', :locals => :object => x
  - result = RubyProf.stop
  - printer = RubyProf::CallStackPrinter.new(result)
  - file = File.open('profile.html', 'w')
  - printer.print(file)
  - file.close

然后启动应用程序,点击页面几次,然后在我的浏览器中打开新创建的profile.html,看看是哪个部分导致了问题。

【讨论】:

感谢您 - 我遇到了慢速查看问题,我正是这样做才能找到我的问题。 FWIW - 我的问题是一个条目表,其中有一列可以使用 best_in_place 就地编辑。事实证明,每行都有一个包含大量选项列表的 bip 字段并不能快速渲染!【参考方案3】:

NewRelic 和日志很有帮助,但有时您需要更多。 NewRelic 确实有一个免费工具可以帮助您在本地进行挖掘,而 ruby​​-prof 等工具会为您提供信息,但您可能很难知道如何使用它。

我在客户的应用程序中发现了一个注册页面,该页面速度非常慢,没有明显的原因。日志确认它很慢,并且缓慢不是由于 db 造成的,但没有帮助我了解问题所在。

https://github.com/brynary/rack-bug/

比 ruby​​-prof 更容易使用,并且可以在您需要深入研究时快速打开/关闭。在帮助人们调整他们的 Rails 应用程序时,我一直使用它。它帮助我了解了哪个部分是慢的,并且经过一些试验和错误,我发现它是注册页面上的时区下拉列表

在一页上是(慢版本):

另一个是: "太平洋时间(美国和加拿大)" %>

我之前/之后的数字:

orig template render          1392.91
fixed template render         165.56
fixed on REE instead of 1.8.7 100.70

我没有进一步挖掘,因为我还有其他问题要解决,但可以缓存时区并获得更快的响应。

【讨论】:

你是怎么解决这个问题的?我们看到了同样的事情——我们的应用程序中有 4 个页面呈现时区(仅限美国),它们的呈现时间始终超过 1200 毫秒。把这条线拿出来,总共大约 140 毫秒。 我只是使用了 ActiveSupport::TimeZone.us_zones 而不是 TZInfo::Country.get("US").zones。 奇怪 - 我们实际上使用的是 ActiveSupport::TimeZone.us_zones。说到这里,这可能会有所帮助——我们实际上向应用程序添加了一个初始化程序来加载时区——只需将其设置为局部变量即可。我们发现,hte first call lo load time zone 花了很长时间,但在那之后它们就变得活泼了。因此,添加初始化程序调用为我们解决了这个问题 - 加载应用程序需要额外的时间,但不会影响性能。【参考方案4】:

如果您没有这样做,请先检查应用程序文件夹中的文件夹log。它包含您应用的每个环境的日志文件。

为了分析 Rails 应用程序,请将您的测试放入文件夹 your_app/test/profile

http://ruby-prof.rubyforge.org/

【讨论】:

这没有提供关于视图的哪个部分花费最多时间的信息,并且来自应用程序的 env/logs 只给出了粗略的时间,例如渲染部分需要多长时间。

以上是关于Rails 中的分析视图的主要内容,如果未能解决你的问题,请参考以下文章

(Rails)从不同视图中的控制器访问方法

Rails 中的高级/基本和智能手机视图

更改 Rails 中的默认视图路径?

从 Rails 中的视图选择或创建

Rails:视图中的两个属性不同的表

删除视图 Rails 中的重复项