Laravelから余計なもの消して最大1.8倍速くする方法


Laravelの高速化手法は色々とあるのですが、具体的な効果を示した記事があまりなかったので、それっぽく測定した記事となります。

完璧から程遠い検証方法になりますので、速くなる可能性が高いぐらいで見ていただけると幸いです。


## 検証環境

```txt
# ハードウェア
MacBook Air (Retina, 13-inch, 2019)
プロセッサ: 1.6 GHz デュアルコアIntel Core i5
メモリ: 8 GB 2133 MHz LPDDR3

# ソフトウェア
docker: 24.0.2
PHP: 8.2
Laravel: 10.29
※ Laravel/sailにて検証
```

### Laravel/sailで設定した内容

.envにて`APP_DEBUG=false`に設定
`composer dump-autoload -o`でautoloadの最適化を実行
検証毎にdockerのコンテナをリスタート

### 検証内容

トップページに対してk6を使い60秒間負荷テストする（仮想ユーザーは1で実施）

## 結論

|  | Http request duration (avg) | Requests/sec	 |
| - | - | - |
| デフォルト | 118.69ms | 8.37889/s |
| ファサードの削除 | 111.85ms | 8.890097/s |
| 利用していないServiceProviderを除外 | 100.73ms | 9.863354/s |
| middlewareを削除 | 69.81ms | 14.205677/s |
| 上の3つを全部実行 | 65.65ms | 15.098335/s |

特にmiddlewareの処理を削除するのが効果的なようでした。
他の処理に関しては誤差ぐらいですね。
118.69 / 65.65 = 1.80倍ほど応答速度が速くなりました。


## 具体的にやったこと

### ファサードを削除する

```diff:config/app.php
-    'aliases' => Facade::defaultAliases()->merge([
-        // 'Example' => App\Facades\Example::class,
-    ])->toArray(),
+    'aliases' => [],
```


```diff:routes/web.php
- Route::get('/', function () {
+ use \Illuminate\Routing\Router;
+ 
+ /** @var Router $route */
+ $route = resolve(Router::class);
+ 
+ $route->get('/', function () {
    return view('welcome');
});
```

一見便利なファサードですが、微小なオーバヘッドは存在してるはずなので削除してみます。
パフォーマンスの影響はほとんどないようですが。

Routeのようにデフォルトでファサードを利用している箇所があるので、直接DIコンテナからインスタンスを取得する箇所も所々でてきます。

※ トップページの表示で影響があるのは`routes/web.php`だけなのでここだけ修正しています。

### 利用していないServiceProviderを削除する

```diff:config/app.php
- 'providers' => ServiceProvider::defaultProviders()->merge([
- /*
- * Package Service Providers...
- */
- 
- /*
- * Application Service Providers...
- */
- App\Providers\AppServiceProvider::class,
- App\Providers\AuthServiceProvider::class,
- App\Providers\BroadcastServiceProvider::class,
- App\Providers\EventServiceProvider::class,
- App\Providers\RouteServiceProvider::class,
- ])->toArray(),
+ 'providers' => [
+ \Illuminate\Cache\CacheServiceProvider::class,
+ \Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
+ \Illuminate\Cookie\CookieServiceProvider::class,
+ \Illuminate\Database\DatabaseServiceProvider::class,
+ \Illuminate\Encryption\EncryptionServiceProvider::class,
+ \Illuminate\Filesystem\FilesystemServiceProvider::class,
+ \Illuminate\Foundation\Providers\FoundationServiceProvider::class,
+ \Illuminate\Session\SessionServiceProvider::class,
+ \Illuminate\View\ViewServiceProvider::class,
+ App\Providers\RouteServiceProvider::class
+ ],
```

Laravelの初期起動処理でトップページを表示するのに不要な処理を削除してみます。

ただ昨今はマイクロサービス化などで、全ての機能が必要でない場面も多いと思うので、明らかに使わない機能は初期起動処理から外しても良いと思います。

`\Illuminate\Contracts\Support\DeferrableProvider`を利用して遅延読み込みしているクラスもあるので、この場合はパフォーマンスに影響することはあまりなさそうですが。

※ 初期起動処理の定義は`ServiceProvider::defaultProviders()`に記載されています

### Middlewareを削除する

```diff:
    protected $middleware = [
-        \App\Http\Middleware\TrustHosts::class,
-        \App\Http\Middleware\TrustProxies::class,
-        \Illuminate\Http\Middleware\HandleCors::class,
-        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
-        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
-        \App\Http\Middleware\TrimStrings::class,
-        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];
```

こちらもServiceProvider同様にプロダクトによっては不要な物が多いです。
精査などせず全て無効化してみます。