Muchos desarrolladores y diseñadores que emprenden la utilización de Odoo como ERP suelen escaparle al website, por su poca oferta a nivel visual, por la curva de aprendizaje de su framework JavaScript pero, más que nada, porque a pesar de ser una plataforma que se actualiza cada año rankea muy mal en los test de PageSpeed más usados de la web. En GTMetrix no llega ni al 50% de performance, en LightHouse un website de Odoo con unas pocas imágenes no consigue más del 35%, y un largo etc. El PageSpeed, pese a la creencia popular, no afecta directamente al posicionamiento; pero afecta el tiempo de permanencia de un usuario, lo cual afecta al negocio, al porcentaje de rebote y, eventualmente, al posicionamiento. En esta serie de entradas en el blog de Codize vamos a ver un poco como se puede mejorar la velocidad del sitio web, veremos cuanto jugo se le puede sacar a la plataforma y si es capaz de competir. En este primer capítulo todo lo relacionado a imágenes.
Guardar las imágenes en módulos
El sistema de carga de imágenes de Odoo es cómodo y está optimizado... hoy. La verdad es que pasan los meses y comprimir dichas imágenes en una herramienta externa da mejores resultados. Sin contar que hay sitios web en Odoo que han quedado muchas versiones atrasados, siempre es mejor tener las imágenes en un módulo, comprimirlas a gusto, tenerlas siempre disponible sin depender del FileStore y de paso hacer más fácil la eventual migración. ¿Es más incómodo? Desde luego, pero hablamos de cumplir con el pedido de optimizar el sitio web. Los builders como el de Odoo nunca van a estar 100% optimizados, solo son más cómodos.
Formatos de la nueva Generación
Típico consejo de LightHouse de Google, pero no es menor: JPG y PNG son formatos estándares pero demasiado pesados. Entiéndase bien, si el sitio web tiene como imágenes 1 logo y un par de banners chicos, entonces no consideraría el esfuerzo de utilizar formatos novedosos. Pero los sitios webs de Odoo normalmente son para negocios, buscan atraer, por lo tanto buscan ser llamativos y eso, generalmente, se da por medio de recursos visuales. En mi experiencia, hoy por hoy el promedio de imágenes principales que lleva un website son alrededor de 5 (cinco), sumadas a unas 8 (ocho) imágenes de menos peso (como logos, fondos tipo mosaico, etc). En este caso si es aconsejable utilizar formatos como WebP. No es el único, se están poniendo fuertes formatos como AVIF o JPG XML, los cuales tienen un rendimiento incluso mejor que WebP. El problema es la compatibilidad, mientras que WebP a día de hoy es soportado por el 94% de los usuarios de internet, AVIF solo es soportado por el 64%. Pero por suerte existe la tag PICTURE, que fue pensada para estos casos:
<picture>
<source srcset="imagen.jxl" type="image/jxl"/>
<source srcset="imagen.avif" type="image/avif"/>
<source srcset="imagen.webp" type="image/webp"/>
<source srcset="imagen.jpg" type="image/jpeg"/>
<img src="imagen.jpg"/>
</picture>
Es un poco más costoso que implementar las imágenes con la tag IMG en Odoo, también hay que codear un poco más, pero sigue siendo solo HTML. En este caso, el navegador va a buscar primero el source que está en la posición uno (JXL en esta oportunidad). Si no lo soporta pasa al siguiente. Si no soporta ninguno va a cargar la tag IMG, y si no soporta PICTURE entonces solo va a cargar IMG. Por lo tanto es compatible con Internet Explorer (tiene todavía un 1% del mercado global). Recomiendo siempre evaluarlo y tenerlo en cuenta, a lo mejor no hace falta tener todos los formatos, pero WebP y JPG me parece adecuado.
Reservar el espacio para el contenido
Los viejos diseñadores se acuerdan de agregar los atributos width y height a las tag IMG. Esta práctica quedo en desuso a favor del CSS responsivo, pero ahora se vuelve a recomendar. Es muy sencillo, el contenido a nivel HTML va a cargar antes que las imágenes, y por lo tanto el espacio entre la imagen y el contenido se va a estirar al momento de cargar la imagen (lo habrán visto). Si el width y height de una imagen están configurados, entonces el navegador va a reservar esos píxeles para mostrar una imagen cuando la misma se cargue; produciendo que el contenido ya cargado no deba volver a adaptarse. Esa re-adaptación produce que el navegador deba renderizar todo el layout nuevamente, consumiendo CPU y aumentando los tiempos de carga, perjudicando la experiencia de usuario. Por lo tanto, es conveniente modificar las tag IMG de Odoo para que queden con su width y height, por ejemplo:
<img src="imagen.jpg" width="400" height="300" />
Imágenes Responsivas, pero de verdad
Nos hemos acostumbrado al uso del bootstrap para que las imágenes se adapten a las distintas resoluciones pero, ¿es realmente la solución? En su momento se agregó un atributo interesante conocido como srcset, el cual no se ve mucho y, desde ya, no viene en el builder de Odoo. Pero se puede agregar facilmente a la tag IMG, nos permite cargar un recurso de imagen con determinada resolución para determinada resolución de pantalla. Esto es mucho más eficiente en la carga que bootstrap, ya que el sistema de bootstrap solo adapta la imagen a las resoluciones más chicas, obligando a un dispositivo más pequeño a cargar una imagen de una resolución mayor.
<img src="imagen-800w.jpg"
width="400"
height="300"
srcset="imagen-400w.jpg 400w,
imagen-800w.jpg 800w" />
Esta simpleza puede ahorrar mucha velocidad en celulares. Dentro de srcset se configura la ruta a la imagen y el tamaño máximo de resolución en width donde se va a cargar dicha imagen. Luego se pueden agregar imágenes para cada uno de los breakpoints separando las rutas por comas. En este ejemplo, si un usuario ingresa con un dispositivo de resolución 400 de width, entonces va a cargar una imagen de 400 píxeles; la cual pesa mucho menos que la de 800 que está puesta por defecto. Este atributo de srcset funciona con las tag SOURCE de PICTURE.
El bendito Lazy Loading
Se ha tardado una vida en que esto exista en internet, es simple y lo soportan bastantes navegadores, un 74% del mercado global a día de hoy (por favor Safari y Opera Mini, faltan ustedes). Es muy sencillo de utilizar y es aconsejable que lo tengan todas las imágenes:
<img src="imagen.jpg" width="400" height="300" loading="lazy" />
El atributo loading, perteneciente a las tag IMG y a la IFRAME, le indica al navegador que dicha imagen debe ser cargada solo si la persona que está navegando necesita verla. Esto es ideal para landing pages. En Odoo 14 cualquier imagen que se suba desde el builder va a tener dicho atributo (una buena), pero en versiones anteriores hay que agregarlo desde el código. Nada complejo.
¿Cómo se aplica todo junto?
Al momento de cargar una imagen en un módulo de Odoo, podemos optar por no usar múltiples formatos, o por no usar un sistema altamente responsivo. Esto con el objetivo de aligerar trabajo. Sin embargo, si queremos aplicar todo, esto es lo que tendremos que hacer a cada imagen:
<picture>
<source srcset="/custom/static/src/img/imagen.jxl 800w,
/custom/static/src/img/imagen-400.jxl 400w" type="image/jxl"/>
<source srcset="/custom/static/src/img/imagen.avif 800w,
/custom/static/src/img/imagen-400.avif 400w" type="image/avif"/>
<source srcset="/custom/static/src/img/imagen.webp 800w,
/custom/static/src/img/imagen-400.webp 400w" type="image/webp"/>
<source srcset="/custom/static/src/img/imagen.jpg 800w,
/custom/static/src/img/imagen-400.jpg 400w" type="image/jpeg"/>
<img src="/custom/static/src/img/imagen.jpg" loading="lazy" width="400" height="300" />
</picture>
¿Para cada imagen hacer esto? No es tanto, lo complicado son los formatos, como opinión particular, me decantaría por usar solo WebP que tiene una excelente cobertura y compresión.