Laravel を高速化というか最適化する
この記事は Laravelリファレンス発売記念!販売促進!! Advent Calendar 2015 - Adventar 12/5 分の記事です。
Laravel について「遅い」とか言われるたびに、「ちゃんと最適化してる?」って思ってたので良い機会なのでここらへんちゃんと書いておこうと思います。
まずは、アプリケーションのコードを一切変えないお手軽な方法から。
コードを修正しないお手軽な方法
optimize コマンド
これ、デプロイ時は必須です。やってくることは
composer dump-autoload --optimize
psr
オプションつけるとcomposer dump-autoload
になる。- 参考: composer installをproduct環境で使う際はoptimize-autoloaderオプションを使おう
- フレームワークのコード結合して一つのファイルに纏める
/bootstrap/cache/compiled.php
に出力/bootstrap/autoload.php
でファイルが存在すればそちらをrequire
してる- 結合対象ファイルは framework/config.php at 5.1 · laravel/framework · GitHub
config/compile.php
のfiles
ブロックににキャッシュ対象のクラスを書けば一緒に結合されるのでオススメ。
注意点としては config/app.php
の debug
が true
だと clear-compiled
が走るだけで終了するので、本番時はちゃんと false
を設定しよう。
route:cache コマンド
ルート定義をキャッシュします。実際何してるかというと、ルート定義をシリアライズして base64_encode
したものを /bootstrap/cache/routes.php
に出力しています。
注意点としては、routes.php
にクロージャを書いている場合はシリアライズできなくてエラーになる。以下の様なルート定義はダメということです。
Route::get('home', function(){ return view('home'); });
キャッシュしたければコントローラーを作ってルート定義しよう。
config:cache コマンド
設定ファイルをキャッシュします。実際何してるかというと、すべての設定値を var_export
して /bootstrap/cache/config.php
に出力しています。
これらのコマンドは使って困ることはないので、デプロイ時には必ず実行させましょう。
番外
これは Laravel に限らないのですが
とかね。早くなりますよ。PHP 7 はともかく OPcache は必ず有効にしましょう。
コードを変更して早くする方法
ここからはコードを少し変更して最適化を目指します。
不要なミドルウェアの削除
App\Http\Kernel
クラスにはグローバルミドルウェアとして幾つかのミドルウェアがあらかじめ登録されています。使わないものを削除してしまいましょう。
- CheckForMaintenanceMode
- メンテナンスモードかどうかをチェックする。メンテナンスモードだったら
503
を返す。
- メンテナンスモードかどうかをチェックする。メンテナンスモードだったら
- EncryptCookies
- クッキーの暗号化。
- AddQueuedCookiesToResponse
- クッキー使わなければいらない(APIサーバーとか)
- StartSession
- セッション使わなければいらない(APIサーバーとか)
- ShareErrorsFromSession
- セッションに
errors
という名前で登録された内容をすべてのビューで共有している
- セッションに
- VerifyCsrfToken
- CRSF チェック。
不要なサービスプロバイダ/ファサードを削除
Laravel は多機能なフレームワークなので、要件には必要のない機能もあると思います。必要のないものは config/app.php
から削除してしまいましょう。
ファサードを使わない
必要なインスタンスをファサードを経由するのではなく、コンストラクタ・メソッドの引数としてインジェクションしたり、コンテナから直接引っ張ってくればファサードは必要なくなります。config/app.php
の aliases
の配列をごっそり削除すれば初期処理は早くなります。
ここらへんは 12/15 に @ex_takezawa さんが詳しく解説してくれると思います。
利便性とトレードオフですが、難易度はさほど高くありません。
Eloquent を使わない
すべての処理を QueryBuilder に任せる方法です。Eloquent はマジックメソッドを多用しているので、使用しないことで若干のパフォーマンス上昇が望めると思います。 こちらはファサードを使わないよりも難易度が高くなると思います。Eloquent を使わないということは…
- リレーション
- Eagerローディング
- マスアサインメント
- 論理削除
- クエリースコープ
- モデルイベント
- アクセサ / ミューテーター
- シリアライズ
の機能が使えないということなので、慎重に検討する必要があります。僕はたぶん無理。
結論
そこまで頑張るんだったら Lumen 使おう。
まとめ
いろいろ最適化の手法を紹介しましたが、いかがでしたでしょうか? まぁ、うん、それでも満足できない場合は Go とか Java 使ったほうがいいと思います。
宣伝
よろしくお願いします!