忙しい人のための結論 (先に結末)
Windows環境のLaravel + Viteプロジェクトで php artisan serve が60秒タイムアウトする原因は、Composerでインストールした postare/blade-mdi パッケージでした。
-
症状:
-
php artisan serveで起動した開発サーバーが、HTMLだけでなくCSSのリクエストにも15秒〜60秒の極端な遅延を発生させていた。
-
-
根本原因:
-
postare/blade-mdiが、アイコンのSVGファイルを探すために、リクエストのたびにプロジェクトのルートディレクトリからnode_modulesを含む全ファイルをスキャンしていたため。
-
-
最終的な解決策:
-
composer remove postare/blade-mdiを実行してパッケージを削除。 - 代替として、パフォーマンスに問題のない
blade-ui-kit/blade-iconsを、アイコンの検索パスを限定する設定で利用する。
-
はじめに
ここから先は、上記の結論に至るまでの、地獄のようなデバッグの全記録です。
これは、ごく普通のLaravelプロジェクトがある日を境に突如としてパフォーマンスの泥沼に沈み、その原因を突き止めるまでの物語です。もしあなたがWindows環境で php artisan serve を使っていて、原因不明の遅延に悩まされているなら、この話はきっと他人事ではないはずです。
私の開発環境:
- OS: Windows
- フレームワーク: Laravel
- フロントエンド: Vite + Tailwind CSS
事件の始まり:CSSからSCSSへ
すべては順調でした。ある時、私はプロジェクトのフロントエンドを近代化するため、標準のCSSからSCSSへ移行し、ViteとTailwind CSSを本格的に導入しました。ローカルでの開発体験も向上するはず…でした。
しかし、その変更をデプロイした直後から、悪夢は始まりました。
php artisan serve で起動したローカルサーバーで、すべてのページの表示に12〜15秒かかるようになったのです。HTMLのレスポンスだけでなく、CSSファイルの読み込みにさえ、同じくらいの時間がかかっていました。
長く、困難な捜査:無実の容疑者たち
ここから、原因を特定するための長い旅が始まりました。AIアシスタントであるGemini 2.5 Proを相棒に、私は考えられるすべての容疑者をリストアップし、一つずつ検証していきました。
-
Viteとセッションの虚偽アリバイ:
最初に疑ったのは、Viteのコンパイルやセッションのファイルロックでした。しかし、npm run devの再実行や、.envのSESSION_DRIVERをfileからdatabase、果てはcookieに変更しても、状況は一切変わりませんでした。彼らは無実でした。 -
Xdebugの冤罪:
次に疑ったのは、デバッグツールXdebugのタイムアウトです。これはWebリクエストで一貫した遅延を引き起こす常習犯として知られています。しかし、php -d xdebug.mode=off artisan serveコンドでXdebugを無効化して起動しても、遅延は解消されませんでした。彼もまた、無実。 -
プロファイラ導入と新たな容疑者たち:
手詰まりになった私は、最後の手段としてプロファイラを導入し、PHPの実行プロセスを徹底的に監視することにしました。データだけが真実を語ります。使用したプロファイラツール
-
データ生成: PHPの拡張機能である Xdebug には、デバッグ機能だけでなくプロファイラ機能も組み込まれています。以下の特別なコマンドで
artisan serveを起動することで、リクエストごとの処理内容を詳細に記録したcachegrindという形式のファイルを出力しました。php -d xdebug.mode=profile -d xdebug.output_dir=/path/to/output artisan serve -
データ可視化・分析: 生成された
cachegrindファイルを解析するために、Gemini 2.5 Proにファイルの中身をすべて渡しました。これにより、どの関数の実行にどれだけ時間がかかっているのかを、データに基づいて分析してもらいました。(VS Codeの拡張機能や、WindowsならQCacheGrindといった専用ツールで自分で可視化することもできます)
プロファイラが示した事実
そして、プロファイラは驚くべき事実を示しました。
-
Phar::mapPharという関数が、実行時間の14秒を独占していたのです。
この関数を呼び出していたのは、いずれも開発用のComposerパッケージでした。
nunomaduro/collisionlaravel/pintphpunit/phpunit
私は「犯人を見つけた!」と確信し、これらのパッケージを一つずつ
composer removeで削除していきました。しかし、事態は解決するどころか、さらに悪化します。14秒の遅延は消え、代わりにPHPの実行時間が60秒を超えてタイムアウトするという、さらに深刻なエラーに変わってしまったのです。 -
データ生成: PHPの拡張機能である Xdebug には、デバッグ機能だけでなくプロファイラ機能も組み込まれています。以下の特別なコマンドで
真相解明:最初の直感は正しかった
phpunitを削除したことで、14秒の遅延という「目くらまし」がなくなり、ついに真のボトルネックが姿を現しました。エラーのスタックトレースが指し示していたのは、symfony/finder というファイル検索コンポーネント。PHPがプロジェクト内のどこかのディレクトリを丸ごとスキャンしようとして、60秒以内に終わらずに力尽きていたのです。
スキャン対象として最も怪しいのは、フロントエンド開発でおなじみの、数十万のファイルがひしめく node_modules ディレクトリです。
ViewやBackupの設定ファイルで node_modules を除外しても効果はありませんでした。そして、私は最後の実験に踏み切りました。
犯人は お ま え だ!!
捜査が振り出しに戻り、手詰まりになった私にとって、改善のきっかけとなったのは、容疑者だった2つのアイコンパッケージを同時に削除してみるという操作でした。
composer remove blade-ui-kit/blade-icons postare/blade-mdi --dev
このコマンドを実行したところ、パフォーマンスは劇的に改善。ついに長いトンネルを抜けました。
犯人がこの2つのうちのどちらか(あるいは両方)であると確信した私は、最後の検証を行いました。
-
blade-ui-kit/blade-iconsをcomposer require→ 問題は再発せず。 彼は無実でした。 - そして、興味本位で
postare/blade-mdiをcomposer requireした、その瞬間…
遅延が、完全に、再発しました。
犯人は お ま え だ!! postare/blade-mdi !!
このパッケージが、アイコンのSVGファイルを探すために、プロジェクトのルートディレクトリから node_modules を含む全ファイルをスキャンしていたのです。これが、この長く困難な事件の全貌でした。
教訓と解決策
今回の事件から、私はいくつかの重要な教訓を得ました。
-
php artisan serve環境下での開発用パッケージの挙動には注意が必要。特にファイルシステムをスキャンする機能を持つものは、Windows環境ではパフォーマンスのボトルネックになりやすい。 - 原因不明の遅延に遭遇したら、推測で戦うのではなく、ためらわずにプロファイラを導入すべき。データは嘘をつかない。
- 一つの問題を解決したら、その下に隠れていた、より大きな問題が姿を現すことがある。
最終的に、私は問題の postare/blade-mdi を削除し、無実だった blade-ui-kit/blade-icons を、アイコンの検索パスを resources/svg に限定する設定で利用することで、SVGアイコンの利用と快適な開発速度の両立を実現しました。