0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Laravel 9.x】Bladeコンポーネント×Eloquentコレクションは速度に注意?

Posted at

こんにちは、現在エンジニアを目指して勉強中の一般男性です。

ポーフォリオ作品を制作しているなかで
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件も取ってこない程度。
何万とかそういう話ではありません。。

事件を時系列で追っていきます

発生当時の状況

繰り返し使っていた要素があったので、
セコセコとコンポーネント化していました。

コンポーネント化が済んだところで画面を確認してみると、、
スクリーンショット 2023-01-25 16.55.41.png

なんでやねーん
何回ロードしてもタイムアウトです

現場を確認

今回のコードは以下のような感じです。
3つの箇所をコンポーネント化していました。
※表示の関係でHoge.htmlとしていますが、本来はブレードテンプレートです
※簡素化しています

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に変更してみました。
変わらず重いまま、、

Hoge.html
<section>
  @include('wishLists', ['wishes' => $wishes])
</section>

<section>
  @include('slider', ['notes' => $notes])
</section>

<section>
  @include('notes', ['notes' => $notes])
</section>

3, ひとつずつ消してみる

コンポーネント化したこと自体ではなく、3つのうちどれかに原因があるのでは、、
ということでひとつひとつ消してみました。

するとここでヒット、、!!
どうも、$wishesが重いらしい。。

4, 変数の中身を確認

ということで、$wishes$notesの中身を確認。

Controllers/HogeController.php
$wishes = Wish::with('user')->where('pref_id', $pref_id)->get();
Controllers/HogeController.php
$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からクエリビルダへ
ビクビクしながら変更。

Controllers/HogeController.php
// これを、、
// $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コンポーネントでやり取りしたら
重くなったという話はパッと出てこなかったので、
誰かの参考になれば幸いです。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?