LAZY LOADING VS EAGER LOADING EN LARAVEL

En Laravel, cuando se trabaja con relaciones entre modelos (hasMany, belongsTo, etc.), Eloquent ofrece dos formas principales de cargar los datos relacionados: Lazy Loading (carga perezosa) y Eager Loading (carga ansiosa o precarga). La diferencia principal está en cuándo y cómo se ejecutan las consultas a la base de datos. Una mala elección puede causar el famoso problema N+1.
  • Lazy Loading: Es el comportamiento por defecto y es lo que pasa cuando se accede a una relación como si fuera una propiedad normal:

    // Modelo Post tiene relación comments() hasMany
    $posts = Post::all();  // 1 sola consulta
    
    foreach ($posts as $post) {
        echo $post->comments->count();  // ← Aquí se dispara una consulta POR CADA post
    }
    
    Se produce 1 consulta para obtener los posts y por cada post una consulta por cada post cuando se accede a "$post->comments". Resultado: Si se obtienen 100 posts → 101 consultas (1 + 100) → Problema N+1.

    Ventajas: Es simple y automático. No se cargan datos que quizás no se usen y es ideal para 1 solo registro o cuando no se se sabe si se va a necesitar la relación.

    Desventajas: Muy fácil caer en N+1 en listas, loops, vistas con foreach y Mal rendimiento con muchos registros.

  • Eager Loading: Se cargan las relaciones de una vez junto con el modelo principal, usando "with()":

    // Carga posts + todos sus comments en solo 2 consultas
    $posts = Post::with('comments')->get();
    
    // O con varias relaciones
    $posts = Post::with(['comments', 'author', 'tags'])->get();
    
    foreach ($posts as $post) {
        echo $post->comments->count();  // ← ¡No dispara consultas nuevas!
    }
    
    Se produce 1 consulta para posts y 1 consulta para todos los comments de esos posts (usa WHERE IN). Total: 2 consultas aunque haya 1000 posts.

    Ventajas: Elimina (casi siempre) el problema N+1. Es mucho más rápido en listas y vistas y se tiene Control total sobre qué relaciones cargar.

    Desventajas: Si se cargan relaciones que no se usan → desperdicio de memoria y tiempo y saber de antemano qué se va a necesitar.

Tabla resumen

Aspecto Lazy Loading Eager Loading
Cuándo se carga Solo al acceder (on-demand) Al inicio, junto con el modelo principal
Número de consultas 1 + N (N = número de registros) Generalmente 1 o pocas (independiente de N)
Problema N+1 Sí, muy común No (lo previene)
Sintaxis principal $model->relacion Model::with('relacion')->get()
Mejor para 1 registro o relaciones opcionales Listas, loops, vistas con datos relacionados
Rendimiento Malo en colecciones grandes Excelente en colecciones grandes
Por defecto en Eloquent No (hay que indicarlo)