Rails 中的分析视图
Posted
技术标签:
【中文标题】Rails 中的分析视图【英文标题】:Profiling view in Rails 【发布时间】:2011-02-14 07:27:52 【问题描述】:我有一个大视图,需要很长时间才能完成渲染内容。最好的剖析方法是什么,视图的哪个部分花费的时间最多?我已经阅读了有关 ruby-prof 的信息,但我不确定在哪里放置它来分析视图渲染。如果存在其他选项,我也想知道它们。
【问题讨论】:
日志告诉我们渲染每个部分需要多少时间。您可以拆分视图进行检查。 【参考方案1】:快速解决瓶颈的最简单方法是使用本地工作的 NewRelics 开发者模式。
-
确保您的 Gemfile 中有
ruby-prof
和 newrelic_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 中的分析视图的主要内容,如果未能解决你的问题,请参考以下文章