Existe una herramienta imprescindible para el entorno de desarrollo de laravel que deberías de tener. Se trata de la consola Laravel Debugbar de Barry vd. Heuvel, que entre otras cosas te genera el tiempo de respuesta de servidor. En principio esta disponible para cualquier versión del framework, desde la 4 hasta la más nueva 5.6 a día de hoy.
¿De dónde surge el problema?
El problema de laravel muchas veces, aunque utilizamos «cache» son las facilidades que ofrece el Eloquent ORM a la hora de vincular diferentes tablas y de establecer relaciones. Esa facilidad si nos descuidamos puede llevar a una complejidad de N^2 e incluso N^N. Es decir, el problema reside en esto:
1 2 3 4 5 |
$posts = Post::all(); foreach($posts as $post) { echo $post->user->name } |
Esto deriva en un numero de consultas enorme, siempre que accedas a «user->name» desde un «post», se realizara una consulta. En principio no es un problema cuando lo haces desde una entrada suelta, pero se puede convertir en un problema cuando lo haces desde una lista de «posts» y quieres mostrar el autor o con los comentarios.
Es decir, si tienes 25 entradas, se realizara una consulta por la entrada en si y otras 25 por cada nombre de usuario o autor, 26 consultas en total. Para reducirlo a solo dos consultas tendrías que hacer algo así:
1 2 3 4 5 6 7 8 9 |
$posts = Post::with('user')->all(); foreach($posts as $post) { echo $post->user->name } // Tendrías solo estas dos consultas // 1. Select * from posts // 2. Select * from users where id in (1, 2, 3, 4, 5, 6, 7) |
Esto en cuestión se llama «eager loading», si quieres profundizar en el concepto, surfeando internet.
¿Cómo controlarlo efectivamente?
El problema reside es que es MUY FÁCIL olvidar de este concepto, dada la facilidad que ofrece Laravel a la hora de desarrollar. De ahí que existe un «añadido» a Laravel hecho por uno de los grandes. Se trata de Laravel Debugbar.
Se soluciona instalando el citado complemento de una forma muy simple. Te dice en tiempo real el numero de consultas» que realiza tu app, el tiempo de respuesta, los «headers», sesiones, las «views» que se generan… etc. Todo de una forma muy intuitiva.
Se instala muy fácil con el composer: «composer require barryvdh/laravel-debugbar –dev», la tienes tanto para la versión 4 del framework, versiones > 5.5 y la mas reciente 5.6. Te recomiendo que visites su github (https://github.com/barryvdh/laravel-debugbar) para los detalles de la instalación de cada versión.
Ejemplo real de lo que ofrece Laravel Debugbar
Por ejemplo cogemos este código y desactivamos cache:
1 2 3 4 5 6 |
Cache::forget("conciertos-en-{$provincia->provincia}"); $conciertos = Cache::remember("conciertos-en-{$provincia->provincia}", 10, function () use ($provincia) { return $provincia->conciertos() ->where('hora', '>=', new DateTime('today')) ->orderBy("concerts.hora", "ASC")->get(); }); |
Obtenemos nada mas y nada menos que 90 consultas:
Ahora volvemos a aplicar el cache y añadimos los parámetros «with» (recuerda primero añadir los parámetros, recargar y eliminar el «forget», si no tiraras de las consultas que tienes en el cache):
1 2 3 4 5 6 7 8 9 |
$conciertos = Cache::remember("conciertos-en-{$provincia->provincia}", 10, function () use ($provincia) { return $provincia->conciertos() ->with('spot') ->with('poster') ->with('artistas') //->with(['spot', 'poster', 'artistas']) ->where('hora', '>=', new DateTime('today')) ->orderBy("concerts.hora", "ASC")->get(); }); |
Obtenemos tan solo 7 consultas, añadiendo 3 o una linea de código, según te guste:
No hace falta comentar, lo que afectaría esta optimización en el rendimiento general de la aplicación. De hecho esto es un ejemplo real, donde se me olvido que citaba a los artistas en el LD+JSON que ni siquiera es visible para el usuario, tan solo para el Bot de Google.
Este articulo es la segunda parte de la optimización de tiempo de respuesta de Laravel, que puedes encontrar aquí.