speed_gun で Rails のパフォーマンスを測定する
Web アプリケーションのパフォーマンスにうるさいみなさんこんにちは。
Rails アプリのパフォーマンスプロファイリングだと、 rack-mini-profiler が有名で、それ以外だと New Relic とかを使って測定していくのが普通のようですが、物足りない部分があったので、自前でプロファイラ gem を作りました。
Rubygems: http://rubygems.org/gems/speed_gun / Github: https://github.com/rosylilly/speed_gun
詳細は Github の README なんかを見ていただくとして、基本的には rack-mini-profiler 的な情報収集が出来ると思ってもらって差し支えないです。
ちなみに計測画面はこんな感じ。
小さくて何も見えないかも……とりあえず3セクションあって、
- ブラウザの UserAgent や Performance API などの結果
- プロファイル結果
- Rack ENVs
となっています(ちなみに画像は Redmine に導入してみたところです。 Gemfile に gem 'speed_gun'
って書いたら OK でした)。
rack-mini-profiler には GC を測定する機能とか ruby-prof との連携機能とかあるんですが、一旦その辺はのせていません。もしかしたらあとで実装するかも。
speed_gun はとにかく手早く Rails のプロファイルを取れるように気を使っています。カスタムプロファイラも手軽に作れるようにしています(README の通り)。
また、 JS のプロファイル結果を speed_gun に送るのも簡単に出来るようにしてあります。1つの画面を皆で共有することで、違うブラウザ間でのパフォーマンス測定をより効率的に行えるようにするためです。
Web アプリケーションの『パフォーマンス』は様々なレイヤがあり、Rails のログからだけでは、本当のボトルネックがどこなのかを認識するのが困難だと思っています。たとえば、 Rails は高速に返しているけど、 JS ですごく重い処理があって『パフォーマンス』が悪い気がする、などです。
重いサイトを見てもユーザーさんは『重い』としか言ってくれないので、どこが重いのかを検証するために作りました。
まだまだドキュメント整備不足なので、もっと増やしていくつもりです。
実験的な機能 SpeedGun::Hook
speed_gun には SpeedGun::Hook
というクラスがあり、これを継承して #invoke
を生やしておくと、そこに保存された SpeedGun::Profiler
のインスタンスが渡るようになっています。
Javascript プロファイリングの都合上、同じ ID の SpeedGun::Profiler
インスタンスが数度呼び出される部分に考慮してコードを書いておくことで、パフォーマンス情報をどこかに永続化する、といったことも可能です。
この辺はまだ API を固めきれていないので今後変更される可能性がありますが、とりあえず僕が試しに使って使用感を確かめようかなというところです。
それでは!