WordPress, Local y los problemas con el TTFB

Después de la reinstalación del ordenador hace unas semanas, el otro día empecé a notar que mi entorno de desarrollo local iba un poco lento.

He pasado por muchos entornos de desarrollo local desde el uso de un servidor externo en la red local, WAMP, máquinas virtuales, crear entornos con Ansible y VirtualBox, o VVV que quizás fuese el que utilicé durante más tiempo.

Pero después de algunos problemas con VVV, cambié a Local by flywheel que inicialmente utilizaba contenedores en una máquina virtual. Su última version, Local Lightning se iniciaba y ejecutaba muchísimo más rápido al prescindir de la máquina virtual y ejecutar el stack nativamente en cada sistema.

Local services
Ruta de Local en C:\Users\USUARIO\AppData\Roaming\Local\lightning-services

Todo iba bien hasta que la semana pasada empecé a notar unos TTFB muy altos, de más de 2 segundos.

Local TTFB

Así se hacía imposible trabajar, porque determinadas peticiones AJAX tenían que esperar muchísimo tiempo y por cada mínimo cambio en el código las actualizaciones se hacían eternas. Porque aunque solo sean dos o tres segundos, se está cambiando el código continuamente y no es viable para un trabajo regular.

Después de buscarle las posibles causas tanto por internet como en el propio Local, cambiar algunas opciones de configuración, desactivar el Debug de PHP, etc., no encontré ninguna característica que me devolviese los tiempos normales.

Si ejecutaba un archivo TXT, HTML, etc. se veía que los tiempos de TTF estaban en torno a 5 milisegundos. Entonces creé un archivo PHP con un bucle de 10.000 iteraciones y volcado de HTML, los tiempos también estaban en el orden de milisegundos.

La siguiente prueba fue crear un nuevo sitio web sin ningún plugin y con el tema por defecto, pero los tiempos seguían siendo muy altos.

Cambié entre Apache y Nginx, entre las diferentes versiones de PHP y los tiempos seguían sin bajar. Fue entonces cuando me decidí a crear una maquina virtual en Hyper-V e instalar un Ubuntu 20.4

Una vez arrancada la máquina virtual, instalé Local y al crear un nuevo sitio en WordPress los tiempos devueltos eran de entre 20 y 50 milisegundos, por lo que el problema estaba con el Local de la instalación de Windows 10.

Solucionando por la vía rápida (o eso creía)

Cómo quería solucionar rápidamente el problema para una web, busqué una alternativa a Local pensando en arreglar a posteriori el problema con Local.

En la gran comunidad de El Arroyo Dev (junta de vecinos), Fernando García Rebolledo me recomendó utilizar Lando. Instalar y funcionar, una maravilla… me decían… me puse con su instalación y configuración y después de algunos problemas de permisos y carpeta personal de SSH seguía sin funcionarme la instalación de Lando, eso sí, de los errores más chulos que he visto 😉

Error Lando

Buscando información sobre mis problemas con Lando, he visto que por tiempos de respuesta, performance, etc. la mejor opción era utilizar WSL 2 para Docker Desktop.

Pero después de intentar forzar la instalación de la versión 2020 de Windows 10 para tener WSL 2, aunque inicialmente me dice que todo está correcto, finalmente no me deja instalar por mi configuración específica por alguno de los problemas no resueltos. Aunque inicialmente me fastidiaba, creo que esto es un avance; si una actualización de Windows da problemas no resueltos con tu configuración específica, no te permite instalarla.

Eso si, parece que a todo el mundo le funcionaba menos a mi 😄

El Arroyo Lando

Vuelvo a pelearme con Local

Debido a la falta de WSL 2 para mi configuración, dejo mis problemas con Lando para cuando tenga WSL 2 y me decido a volver a intentar solucionar el problema de Local.

Probé Local en otra instalación de Windows 10 en mi portátil y ahí veo que creando tres nuevos sitios web de WordPress con las tres opciones disponibles de base de datos (MariaDB 10.4.10, MySQL 8.0.16 y MySQL 5.7.28) una de ellas, la de MySQL 8 daba unos tiempos de rendimiento muy bajos, con lo cual estaba claro el problema era con la base de datos.

Volví a la instalación del PC de escritorio y empecé a realizar un «Debug de pobres 😄» como me recomendó Adrián en la comunidad del Arroyo (¿o fue en un cafelito WP?).

Lo primero que hice fue un PHP que solo incluía el wp-config.php de WordPress y los tiempos eran altos. Si en el wp-config.php comentaba la última línea, la que incluía el wp-settings.php entonces los tiempos volvían a los 5 milisegundos.

Abriendo el archivo wp-settings.php fui directamente a la línea 126 dónde se llaman las funciones de la base de datos (require_wp_db();), si ahí realizo un die() antes de la función, los tiempos se mantenían en los 5 milisegundos, con lo cual era evidente que el problema es en la conexión entre PHP y la base de datos.

Los tiempos excesivos son previos a la realización de ninguna consulta, antes de esto, entre otras muchas pruebas, había utilizado Query Monitor y me daba que los tiempos de las consultas en base de datos eran bajos, porque en realidad el problema era en la conexión con la Base de datos y no en las propias consultas.

El siguiente paso fue buscar el problema de esa lentitud en las conexiones y en este post de hace casi ocho años estaba la posible respuesta: Connecting to MySQL from PHP is extremely slow.

Comprobando los archivos de configuración tanto de MySQL como de MariaDB se veía que la opción de --skip-name-resolve no estaba activa en sistemas Windows.

skip-name-resolve

El problema venía en las búsquedas entre IPv4 e IPv6 y aunque el archivo de hosts tiene el mapeo de IP en IPV4 e IPV6 de la IP a localhost, PHP no lee ese archivo en la conexión con la Base de Datos.

Aunque hay más de una solución para este problema, la opción más rápida, fácil y evidente es modificar el archivo wp-config.php y evitar la búsqueda de DNS cambiando localhost a 127.0 0.1

Probando la solución

Para ver que efectivamente todo funciona bien, he creado un archivo PHP sin nada de WordPress y que simplemente se conecta a la Base de Datos mediante localhost y sin realizar ninguna consulta. Mido tiempos de TTFB y me daba 2,04 segundos:

Conexión DB con localhost
TTFB DB mediante localhost

A continuación se cambia la cadena de conexión a la Base de Datos mediante IP en lugar de nombre host y tenemos los resultados deseados:

Conexión DB con IP
TTFB DB mediante IP

Una vez realizado el cambio la conexión a la base de datos es de 6,60 milisegundos y la ejecución del WordPress vuelve a dar un TTFB de poco más de 20 milisegundos.

Conclusión

En los momentos en los que algo no nos funciona solemos buscar opciones complicadas, cuando a lo mejor el cambio más sencillo y más evidente es la solución buscada.

En este caso era muy fácil hacer la prueba de un PHP en el que iba incluyendo y excluyendo opciones para encontrar el problema, pero cuando tenemos prisa no miramos lo más evidente y acabamos realizando muchas más pruebas de las necesarias y gastando el doble o el triple del tiempo.

De todas formas este problema me ha traído una conclusión muy evidente, y es que en el momento en el que tenga disponible WSL 2, voy a empezar a utilizarla Lando para más de un desarrollo.

Mirando las posibilidades de Lando me ha parecido una solución fantástica y gracias al grupo del Arroyo Dev y a su excelente comunidad he conocido a José Peleato y su charla José Peleato: Lando, la herramienta Docker Human friendly que me había perdido en la WordCamp Spain.

Pero como ya he dicho, por ahora dejo Lando para el momento de en el que tenga disponible WSL 2.

Muchísimas gracias a toda la comunidad del Arroyo Dev y a todos los miembros del Cafelito WP que han aguantado mis errores de Lando, Local y las conversaciones Dev porno de Heidi(SQL) y demás 😄

6 comentarios en «WordPress, Local y los problemas con el TTFB»

  1. Que bueno Carlos!!! como comentábamos y después de una primeras pruebas todo apuntaba a que el problema estaba en la conexión de PHP con SQL…
    Pero como siempre pasa nos ponemos a probar cosas chungas, cuando la «solución» es más sencilla.
    Me encanta lo de «debug para pobres» y fué en un cafelitoWP

    Si saco algo positivo de este confinamiento es la buena amistad que he sacado contigo y poder compartir webonadas y cachondeos por multiples canales.

    Qué feliz de haberte conocido!!

    Responder
    • Gracias Adrián, e igualmente, en este confinamiento me he perdido varias WordCamps físicas, pero en las online me he llevado excelentes amigos de varios rincones de España, entre ellos uno de los alcaldes del fantástico pueblo del Arroyo, el otro alcalde, Fernando, ya estaba entre ese grupo de amigos y excelentes personas.
      Contigo Adrián me he reído un montón en tus charlas, cafelitos y proyectos y espero que sigamos compartiendo charlas, proyectos, cafés, código, webonadas y risas por mucho más tiempo.
      Lo de el «debug para pobres» creo haberlo oído en algún sitio, en lugar del XDebug o similar, ponemos echo y dies por todos los sitios, tenemos que reconocer que al final es de lo que más utilizamos 😄
      Un gran abrazo.

      Responder
  2. ¡Muy buena investigación Carlos!
    Por lo que veo el skip-name-resolve sólo lo mete en Windows no?
    Seguro que est asolución le facilita a alguien la vida

    Responder

Deja un comentario