YAMLとERBでJSONを書けるハンドラを書いたものの遅くなってしまったので、一旦YAMLとERBのことは忘れ、evalとしては最速になるようにhashをJSONに変換するアプローチで再度書いてみました。

また前回同様、

  • モンキーパッチをしない
  • N+1 find_template_pathsを避ける
  • Railsのcollectionのパーシャルレンダリングの仕組みを使う

というのをコンセプトでやっています。

できあがったものはこれ↓

インストールと使い方

インストールは

でbundle installするだけ。

使い方は amatsuda/jb とほぼ同様の使い方になりますが、パーシャルレンダリングの方法が違います。

パーシャルレンダリングしたい場合は r.(partial: 'xxxx', ....)を呼び出します。

内部のしくみ

Railsのcollectionのパーシャルレンダリングの仕組みを使ってしまうと、レンダリングされた個々のレコードのビューがjoinメソッドによって文字列化+連結されてしまいます。JSONの場合は配列を期待しているので、カンマ区切り連結しつつ先頭と末尾に[]が付いてほしいのですが仕組み上できません。

なので、jvではハンドラー側でよしなに配列のJSON文字列にしています。

rはJv::Renderのインスタンスで、callメソッドで実際のパーシャルレンダリングを行っています。

collectionの引数が指定された場合は_partial: trueを指定してレンダリングします。_partialが定義されていると、hash.to_jsonの後ろにカンマを付けています。

このままjoinすると後ろに余計なカンマができるので削除しつつ、配列の括弧で囲んであげて最後にJSON.loadしてハッシュ化します。

配列結合が無理矢理感満載ですが一応動いているようです。

ベンチマーク

今回は本番環境でjbuilderより〜3倍程度速かったです!

Development

Production

1000件のパーシャルレンダリングでstackprofを取ってみたらこんな感じでした。

特に大きなボトルネックになっているところは無さそうですが、さすがにto_jsonしまくっているのでそこは少し目立ってます。