Eager Loading vs Lazy Loading w Laravel

1. Problem N+1 przy Lazy Loading

Domyślnie Eloquent korzysta z lazy loading. Dane relacyjne są ładowane dopiero przy dostępie.
Często prowadzi to do problemu N+1 zapytań.

$users = User::all(); // 1 zapytanie
foreach ($users as $user) {
    $user->posts; // +1 zapytanie na użytkownika ❌
}

100 użytkowników = 101 zapytań 😱


2. Eager Loading – dobre rozwiązanie

Rozwiązaniem jest eager loading:

$users = User::with('posts')->get(); // łącznie tylko 2 zapytania ✅

Można ładować relacje zagnieżdżone:

$users = User::with('posts.comments')->get();

3. Warunkowe ładowanie relacji

Nie zawsze trzeba ładować wszystkie dane.

  • Filtrowanie relacji
$users = User::with(['posts' => fn($q) => $q->where('is_active', true)])->get();
  • Ładowanie tylko gdy brakuje
$user->loadMissing('posts');
  • Połączenie z filtracją (withWhereHas)
$users = User::withWhereHas('posts', fn($q) => $q->where('is_active', true))->get();

4. Model::shouldBeStrict() – strażnik w developmentcie

Włącz strict mode w AppServiceProvider:

use Illuminate\Database\Eloquent\Model;

public function boot(): void
{
    Model::shouldBeStrict();
}

Korzyści:

  • Laravel rzuci wyjątek przy lazy loadingu w pętli
  • Wykryje nieistniejące atrybuty
  • Bezpieczniejszy workflow w dev

Na produkcji można użyć:

Model::preventLazyLoading(! app()->isProduction());

Dzięki temu w dev są wyjątki, a w produkcji tylko warningi.


5. Checklista dobrych praktyk ✅

  • Używaj with() gdy wiesz, że potrzebujesz relacji
  • Do agregacji stosuj withCount() zamiast ładować całą relację
  • Do warunkowego ładowania używaj withWhereHas
  • Włącz Model::shouldBeStrict() w dev
  • Monitoruj zapytania (Laravel Debugbar, Telescope, Clockwork)
Komentarze (0)
Zostaw komentarz

© 2026 Wszelkie prawa zastrzeżone.