Otra manera de optimizar nuestras consultas es utilizar la característica de paginación de Eloquent para evitar seleccionar todos los datos, y por el contrario obtenerlos en rangos de 15, 20, 50 o 100 resultados por página. En esta lección veremos cómo paginar datos con Laravel y los detalles que debemos tener en cuenta sobre las 2 formas de paginación que nos ofrece el framework.
Esta lección incluye un video premium
Regístrate para ver este video y cientos de lecciones exclusivas.
Mira el código en GitHub: actual, resultado, comparación.
Al utilizar el método all
o llamar al método get
sin especificar ningún tipo de restricción (por ejemplo, a través de where
para agregar una condición a la consulta) obtendremos todos los resultados. Esto es viable únicamente si estamos 100% seguros de que la tabla contendrá pocos registros. Pero si tenemos 1000 productos deberíamos aplicar algún tipo de restricción o paginación de los resultados.
Paginación con Eloquent
Paginar con el ORM Eloquent es sumamente sencillo, cambia el llamado a get
por el método paginate
:
<?php // routes/web.php $products = Product::query() ->select(['title', 'slug', 'image', 'category_id']) ->with(['category:id,title,slug']) ->paginate();
¡Ya casi está listo! La vista resources/views/products.blade.php
no requiere de cambios; sin embargo, para que la paginación sea útil, debemos agregar los enlaces para avanzar o retroceder en el listado de resultados:
@forelse($products as $product) <div class="item"> <!-- información del producto --> </div> @empty <p>No se encontraron productos @endforelse {{ $products->links() }}
Al utilizar el método paginate
, Laravel retorna un objeto de la clase Illuminate\Pagination\LengthAwarePaginator
, este objeto envuelve la colección generada por Eloquent o el constructor de consultas (Illuminate\Database\Eloquent
o Illuminate\Support\Collection
respectivamente).
links
es uno de los métodos que brinda el paginador de Laravel y éste imprimirá el HTML con los enlaces necesarios para la paginación.
Cambiar la cantidad de resultados por defecto con el paginador de Laravel
Por defecto, Eloquent pagina los resultados de 15 en 15, pero podemos personalizar esto como primer argumento del método paginate
:
<?php Product::paginate(20); // Pagina de 20 en 20
O cambiando la propiedad $perPage
en el modelo:
<?php namespace App; //... class Product extends Model { protected $perPage = 20; }
Regresa el navegador y recarga la página para ver el resultado. Podrás ver que la cantidad de productos ha aumentado y el total de páginas ha disminuido.
Consultas ejecutadas por el paginador de Laravel
El paginador genera dos consultas:
La primera consulta sirve para contar la cantidad de productos que hay en el sistema y la segunda consulta obtiene los primeros 15 resultados.
Si cambiamos el seeder para generar 100 mil o 1 millón de productos en vez de 1000 y tenemos extrema paciencia, podremos ver que la consulta para contar los productos sube a un tiempo considerable. En mi computador:
- Contar 1000 registros = 500 microsegundos
- Contar 100 mil registros = 2 milisegundos
- 1 millón de registros = 200 milisegundos
En casos así podemos acudir al método simplePaginate
:
<?php // routes/web.php $products = Product::simplePaginate(); // O: $products = Product::query() //... ->simplePaginate();
De regreso al navegador podemos notar que Laravel ya no realiza la consulta para contar la cantidad de resultados. Lo cual reduce de manera considerable el tiempo de procesamiento.
La desventaja de esto es que perdemos la información sobre la cantidad de páginas, puesto que el paginador ahora presenta solo dos opciones para ver la página previa y la siguiente.
Puedes aprender cómo traducir tu aplicación al español si revisas las notas de la lección Validación de datos en Laravel 6.
Personalizar el estilo del paginador de Laravel
Como una nota adicional, si deseas personalizar el HTML generado por el paginador de Laravel utiliza el comando:
# php artisan vendor:publish --tag=laravel-pagination
Luego personaliza las vistas generadas en resources/views/vendor/pagination/
.
También puedes elegir qué vista usar cuando llamas al método links:
<!-- resources/views/products.blade.php --> {{ $products->links('bootstrap-4') }}
Una mejor práctica es ir a app/Providers/AppServiceProvider.php
y cambiar las vistas por defecto:
<?php namespace App\Providers; // ... use Illuminate\Pagination\Paginator; class AppServiceProvider extends ServiceProvider { public function boot() { Paginator::defaultView('vendor.pagination.bootstrap-4'); Paginator::defaultSimpleView('vendor.pagination.simple-bootstrap-4'); } //... }
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.
Lección anterior Tip de optimización con Eloquent #3: Selecciona columnas específicas Lección siguiente Tip de optimización con Eloquent #5: Usa claves foráneas (índices)