こんにちは、現在エンジニアを目指して勉強中の一般男性です。
ポーフォリオ作品を制作しているなかで
Bladeコンポーネントを使おうとした瞬間にページが重くなったので
メモとして残しておきます。
環境
・macOS Monterey 12.6
・PHP 8.1.13
・Laravel 9.3.12
・Docker 20.10.2
・Laravel Sail
前提
LaravelのBladeテンプレートで、
同じデザインの要素を何度も繰り返し表示させていたので、
コンポーネント化してスッキリさせようとした時の話です。
結論、Bladeコンポーネントに渡す変数の中身が
Eloquentコレクションだったことでかなり重くなりました。
ちなみにデータの量ですが、
約10カラムのテーブルから10件も取ってこない程度。
何万とかそういう話ではありません。。
事件を時系列で追っていきます
発生当時の状況
繰り返し使っていた要素があったので、
セコセコとコンポーネント化していました。
なんでやねーん
何回ロードしてもタイムアウトです
現場を確認
今回のコードは以下のような感じです。
3つの箇所をコンポーネント化していました。
※表示の関係でHoge.html
としていますが、本来はブレードテンプレートです
※簡素化しています
<section>
@component('components.wishLists',
['wishes' => $wishes])
@endcomponent
</section>
<section>
@component('components.slider',
['notes' => $notes])
@endcomponent
</section>
<section>
@component('components.notes',
['notes' => $notes])
@endcomponent
</section>
犯人を捜索
どこが悪かったのか探っていきましょう。
1, とりあえず全部もどしてみる
これまでのスピードに直りました。
やっぱりコンポーネント化が原因ぽい。
2, 別の方法でコンポーネント化する
@component
がダメなのかなと思い、@include
に変更してみました。
変わらず重いまま、、
<section>
@include('wishLists', ['wishes' => $wishes])
</section>
<section>
@include('slider', ['notes' => $notes])
</section>
<section>
@include('notes', ['notes' => $notes])
</section>
3, ひとつずつ消してみる
コンポーネント化したこと自体ではなく、3つのうちどれかに原因があるのでは、、
ということでひとつひとつ消してみました。
するとここでヒット、、!!
どうも、$wishes
が重いらしい。。
4, 変数の中身を確認
ということで、$wishes
と$notes
の中身を確認。
$wishes = Wish::with('user')->where('pref_id', $pref_id)->get();
$notes = DB::table('notes')
->leftJoin('users', 'notes.user_id', '=', 'users.id')
->where('notes.pref_id', $pref_id)
->where('notes.deleted_at', null);
->select('notes.*', 'users.name', 'users.avatar')
->orderBy('note_id', 'DESC')
->limit(8)
->get();
Eloquentとクエリビルダの違いか、、!?!?!?!?
解決
$wishes
の取得方法をEloquentからクエリビルダへ
ビクビクしながら変更。
// これを、、
// $wishes = Wish::with('user')->where('pref_id', $pref_id)->get();
// こうだっ!!
$wishes = DB::table('wishes')
->leftJoin('users', 'wishes.user_id', '=', 'users.id')
->where('wishes.pref_id', $pref_id)
->where('wishes.deleted_at', null);
->select('wishes.*', 'users.name', 'users.avatar')
->get();
動いたっっっっっ!!!!!!
参考
「laravel Eloquent 遅い」などで検索すると、結構記事が出てきます。
「もう遅くない」という話もありましたが、下の記事は2022/5月のもの。
Eloquentでデータを取得すると、付随するメソッドとかも格納するので重くなる
という解釈ができそうです。
EloquentコレクションをBladeコンポーネントでやり取りしたら
重くなったという話はパッと出てこなかったので、
誰かの参考になれば幸いです。