DesignAssembler

備忘録に近い

Railsアプリを6倍高速化した話

正確に言えば通常の6倍遅いRailsアプリケーションを通常の速度にした、といった感じです。

まず、こちらを見てください

Completed 200 OK in 3271ms (Views: 53.9ms | ActiveRecord: 2300.6ms)

あぁ・・・・・

ActiveRecord2300msって・・・・あと800msくらいよくわからない時間がある・・・

鈍速なのでレスポンスタイム500msを目指します。

計測

newrelic見るとだいたいどこがボトルネックか分かりました。

f:id:hyottokoaloha:20160505121109p:plain

コントローラーでviewに投げる変数作るときにだいぶ時間食ってますね。

やった事

  • activerecord周りの処理の見直し
  • fragment cacheの使用

この2つでだいぶ速くなりました。

activerecord周りの処理

ログを見るとselect文が大量発生していました。

Article Load (4.2ms)  SELECT  `articles`.* FROM `articles` WHERE `articles`.`id` = 1 LIMIT 1
Article Load (3.9ms)  SELECT  `articles`.* FROM `articles` WHERE `articles`.`id` = 5 LIMIT 1
Article Load (3.2ms)  SELECT  `articles`.* FROM `articles` WHERE `articles`.`id` = 61 LIMIT 1
Article Load (2.8ms)  SELECT  `articles`.* FROM `articles` WHERE `articles`.`id` = 31 LIMIT 1
Article Load (3.1ms)  SELECT  `articles`.* FROM `articles` WHERE `articles`.`id` = 78 LIMIT 1

まずこれをなんとかするためにこのsqlが発行される場所を見ました。そして該当箇所を探してincludesします。

Calendar.includes(article: [:tags])

これで発行されるsql文がスマートになりました。

SELECT `calendars`.* FROM `calendars`  ORDER BY date DESC
  Article Load (1.7ms)  SELECT `articles`.* FROM `articles` WHERE `articles`.`id` IN (1, 61, 27, 129, 127, 131, 142, 128, 30, 83, 84, 29, 85, 137, 19, 80, 28, 159, 78, 90, 35, 79, 149, 31, 134, 77, 87, 156, 163, 157, 133, 81, 17, 88, 138, 24, 151, 89, 93, 130, 152, 153, 154, 140, 161, 135, 145, 144, 155, 86, 82, 164, 41, 139, 132, 36, 162, 160, 95, 96, 62, 148, 166, 92, 25, 141, 165, 143, 136, 18, 21, 147, 20, 146, 34, 52, 150, 94, 46, 53, 91, 39, 23, 22, 38, 158, 167, 47, 33, 37, 42, 45, 63, 32, 43, 48, 40, 51, 49, 44, 168, 54, 56, 169, 179, 180, 184, 50, 65, 171, 172, 173, 177, 178, 181, 182, 183, 55, 170, 64, 66)

ここで時間は

Completed 200 OK in 1052ms (Views: 65.1ms | ActiveRecord: 124.4ms)

とりあえず3倍速ですね。

fragment cacheの使用

ボトルネックの該当viewは全ページに表示されるメニューだったので、キャッシュを使います。

該当viewを以下のように変更します。パーシャル化してあるのでこれだけでOKです。

<% cache("right_menu", skip_digest: true, expires_in: A_DAY) do %>
#該当view
<% end %>

これで時間を見ると

Completed 200 OK in 496ms (Views: 23.1ms | ActiveRecord: 41.9ms)

更に倍速の6倍速!目標に到達しました。

Chromeでの実測だとだいたい+1000msされるのですが、これはAnalyticsやFacebookの読み込みが影響しているようです。どうにかしたいです・・・・・

参考