Mejorar el rendimiento de una tienda en línea (estudio de caso)
Publicado: 2022-03-10Todos los desarrolladores front-end persiguen el mismo santo grial del rendimiento: puntuaciones verdes en Google Page Speed. Siempre se agradecen los signos tangibles del trabajo bien hecho. Sin embargo, al igual que la búsqueda del grial, debe preguntarse si esta es realmente la respuesta que está buscando. El rendimiento de la vida real para sus usuarios y cómo se "siente" el sitio web cuando lo está utilizando no debe descartarse, incluso si le cuesta uno o dos puntos en Page Speed (de lo contrario, todos tendríamos una barra de búsqueda y un estilo sin estilo). texto).
Trabajo en una pequeña agencia digital, y mi equipo trabaja principalmente en grandes sitios web corporativos y tiendas: la velocidad de la página entra en discusión en algún momento, pero generalmente en ese momento la respuesta es que se necesitaría una gran reescritura para realmente lograr cualquier cosa. un desafortunado efecto secundario del tamaño y la estructura del proyecto en las corporaciones.
Trabajar con jewellerybox en su tienda en línea fue un cambio de ritmo bienvenido para nosotros. El proyecto consistió en actualizar el software de la tienda a nuestro propio sistema de código abierto y rehacer la parte delantera de la tienda desde cero. El diseño fue realizado por una agencia de diseño y UX que también manejó el prototipo HTML (basado en Bootstrap 4). A partir de ahí, lo incorporamos a las plantillas y, por primera vez, también teníamos un cliente obsesionado con el rendimiento del sitio web.
Para el lanzamiento, nos enfocamos principalmente en sacar el nuevo diseño, pero una vez que se puso en marcha el relanzamiento del sitio web, comenzamos a centrar nuestra atención en convertir las puntuaciones rojas y naranjas en verdes. Fue un viaje de varios meses lleno de decisiones difíciles, con muchas discusiones sobre qué optimizaciones valía la pena seguir. Hoy en día, el sitio web es mucho más rápido y ocupa un lugar destacado en varios escaparates y puntos de referencia. En este artículo, destacaré parte del trabajo que hicimos y cómo pudimos alcanzar nuestra velocidad.
Las tiendas en línea son un poco diferentes
Antes de entrar en detalles, tomemos un breve momento para hablar sobre cómo las tiendas en línea son diferentes de muchos otros sitios web (si ya lo sabe, nos reuniremos con usted en la siguiente sección). Cuando hablamos de un sitio web de comercio electrónico, las páginas principales que tendrás son:
- la página de inicio (y las páginas de "contenido"),
- categorías y páginas de búsqueda,
- páginas de detalles del producto,
- el carrito y pago (obviamente).
Para este artículo, nos centraremos en los primeros tres y los ajustes de rendimiento para estos. La caja es su propia bestia. Allí tendrá una gran cantidad de JavaScript adicional y lógica de back-end para calcular los precios, además de varias llamadas de servicio para obtener el proveedor de envío adecuado y las estimaciones de precios según el país al que se envía.
Obviamente, esto se suma a la validación de los campos de los formularios que necesitará para registrar las direcciones de facturación y envío. Agregue a eso el acceso directo del proveedor de pago, y tendrá algunas páginas que nadie querrá tocar una vez que hayan sido probadas y funcionen correctamente.
¿Qué es lo primero que piensas cuando imaginas una tienda online? Imágenes : montones y montones de imágenes de productos. Están básicamente en todas partes y dominarán su diseño. Además, querrás mostrar muchos productos para que la gente te compre, así que es un carrusel. ¡Pero espera! ¿La gente hace clic en los productos que contiene? Podemos averiguarlo poniendo algo de seguimiento en el carrusel. ¡Si lo rastreamos, podemos optimizarlo! Y de repente, tenemos carruseles de productos externos impulsados por IA en nuestras páginas.
La cuestión es que un carrusel no será el último elemento de penalización de velocidad que agregue a la página para exhibir más productos con la esperanza de atraer más ventas. Por supuesto, una tienda necesita elementos interactivos , ya sea el zoom de la imagen del producto, algunos videos, una cuenta regresiva para la fecha límite de envío de hoy o una ventana de chat para ponerse en contacto con el servicio de atención al cliente.
Todos estos son muy importantes cuando se miden las conversiones directamente como ingresos . Además, cada pocos meses, alguien del equipo detectará alguna funcionalidad nueva e interesante que podría agregarse, por lo que la complejidad y el JavaScript comienzan a acumularse, a pesar de que comenzó con la mejor de las intenciones para mantenerlo simplificado.
Y aunque generalmente puede almacenar en caché la página completa de un artículo, no ocurre lo mismo con muchas páginas y elementos de la tienda. Algunos son específicos del usuario, como el carrito de compras en el encabezado o la lista de deseos, y debido a la naturaleza personal de los datos, nunca deben almacenarse en caché. Además, si tiene bienes físicos, se trata de un inventario en vivo: especialmente durante la temporada navideña, necesitará que la información sobre el inventario sea precisa y esté actualizada; por lo tanto, necesitará una estrategia de almacenamiento en caché más compleja que le permita almacenar en caché partes de la página y combinar todo de nuevo durante la representación del lado del servidor.
Pero incluso en las fases de planificación, aguardan trampas. En un diseño, y a menudo también en la fase de prototipo, trabajará con nombres y descripciones de productos finamente elaborados, todos de longitud casi uniforme e imágenes de productos ideales. ¡Se ven increíbles! ¿El único problema? En realidad, la información del producto puede tener una longitud muy diferente, lo que puede estropear su diseño. Con varios miles de productos, no puede verificar cada uno.
Por lo tanto, ayuda si los diseñadores o las personas que hacen el prototipo prueban con cadenas muy cortas y muy largas para asegurarse de que el diseño aún se ajuste. Del mismo modo, hacer que la información aparezca dos veces en el HTML, una para escritorio y otra para móvil, puede ser un gran problema para una tienda, especialmente si se trata de información compleja como los detalles del producto, el carrito de compras o las facetas de los filtros en una categoría de producto. página. Es difícil mantenerlos sincronizados, así que ayude a un compañero desarrollador y no lo haga.
Otra cosa que nunca debe ser una ocurrencia tardía y debe incorporarse desde la etapa de prototipo en adelante es la accesibilidad. Existen varias herramientas que pueden ayudarlo con algunos de los conceptos básicos, desde tener texto alternativo para todas las imágenes e íconos con una función, contraste de color, hasta saber qué atributos ARIA usar dónde (y cuándo no). Incorporar esto desde el principio es mucho más fácil que más adelante y permite que todos disfruten del sitio web en el que está trabajando.
Aquí hay un consejo: si no ha visto a personas usar un lector de pantalla o navegar solo con un teclado, los videos sobre esto se pueden encontrar fácilmente en YouTube. Cambiará su comprensión de estos temas.
Volver al rendimiento: ¿Por qué es tan importante volver a mejorar el rendimiento de una tienda? La respuesta obvia es que quieres que la gente te compre . Hay varias formas en que puede afectar esto, y la velocidad de su sitio web es una de las más importantes. Los estudios muestran que cada segundo adicional de tiempo de carga tiene un impacto significativo en la tasa de conversión. Además, la velocidad de la página es un factor de clasificación para la búsqueda y también para sus anuncios de Google. Por lo tanto, mejorar el rendimiento tendrá un efecto tangible en el resultado final.
Cosas prácticas que hicimos
Algunos cuellos de botella de rendimiento son fáciles de identificar, pero una mejora completa es un viaje más largo, con muchos giros y vueltas. Comenzamos con todas las cosas habituales, como volver a verificar el almacenamiento en caché de los recursos, ver qué podíamos obtener previamente o cargar de forma asincrónica, asegurándonos de que estamos usando HTTP/2 y TLSv1.3. Muchos de ellos están cubiertos en la útil descripción general de CSS-Tricks, y Smashing Magazine ofrece una excelente lista de verificación en PDF.
Primero lo primero: cosas cargadas en todas las páginas
Hablemos de recursos, y no solo de CSS o JavaScript (que trataremos más adelante). Comenzamos observando cosas compartidas en múltiples pantallas, cada una de las cuales puede tener un impacto. Solo después de eso nos enfocamos en los tipos de página y los problemas exclusivos de ellos. Algunos elementos comunes fueron los siguientes.
Icono Cargando
Como en tantos sitios web, usamos varios íconos en nuestro diseño. El prototipo venía con algunos íconos personalizados que eran símbolos SVG incrustados. Estos se almacenaron como una gran etiqueta svg
en el encabezado HTML de la página, con un símbolo para cada uno de los íconos que luego se usó como un svg
vinculado en el cuerpo del HTML. Esto tiene el agradable efecto de hacer que estén directamente disponibles para el navegador cuando se carga el documento, pero obviamente el navegador no puede almacenarlos en caché para todo el sitio web.
Así que decidimos moverlos a un archivo SVG externo y precargarlo. Además, incluimos solo los íconos que realmente usamos. De esta manera, el archivo se puede almacenar en caché en el servidor y en el navegador, y no será necesario interpretar archivos SVG superfluos. También admitimos el uso de Font Awesome en la página (que cargamos a través de JavaScript), pero lo cargamos a pedido (agregando un pequeño script que verifica cualquier etiqueta <i>
y luego cargando el JavaScript de Font Awesome para obtener cualquier SVG iconos que encuentra). Debido a que nos apegamos a nuestros propios iconos en la parte superior de la página, podemos ejecutar todo el script después de que se haya cargado el DOM.
También usamos emoji en algunos lugares para íconos coloridos, algo en lo que ninguno de nosotros realmente pensó pero que nuestro editor de contenido, Daena, solicitó y que es una excelente manera de mostrar íconos sin ningún efecto adverso en el rendimiento (la única advertencia es los diferentes diseños en diferentes sistemas operativos).
Carga de fuentes
Como en tantos otros sitios web, usamos fuentes web para nuestras necesidades tipográficas. El diseño requiere dos fuentes en el cuerpo ( Josefin Sans en dos pesos), una para encabezados ( Nixie One ) y otra para texto de estilo especial ( Moonstone Regular ). Desde el principio, los almacenamos localmente, con una red de entrega de contenido (CDN) para mejorar el rendimiento, pero después de leer el maravilloso artículo de Simon Hearne sobre cómo evitar cambios de diseño con la carga de fuentes, experimentamos eliminando la versión en negrita y usando la normal.
En nuestras pruebas, la diferencia visual fue tan pequeña que ninguno de nuestros probadores pudo darse cuenta sin ver ambos al mismo tiempo. Entonces, bajamos el peso de la fuente . Mientras trabajábamos en este artículo y preparábamos una ayuda visual para esta sección, nos topamos con diferencias más grandes en los navegadores basados en Chromium en Mac y los basados en WebKit en pantallas de alta resolución (¡vaya, complejidad!). Esto condujo a otra ronda de discusiones sobre lo que deberíamos hacer.
Después de un poco de ida y vuelta, optamos por mantener la negrita falsa y usar -webkit-text-stroke: 0.3px
para ayudar a esos navegadores en particular. La diferencia con el uso del peso de fuente independiente real es leve, pero no lo suficiente para nuestro caso de uso, donde casi no usamos fuente en negrita, solo unas pocas palabras a la vez (lo siento, aficionados a las fuentes).
Además, varios productos se pueden personalizar con grabados . Estos grabados se pueden realizar en múltiples fuentes, y para algunos ofrecemos una vista previa con la fuente aplicada. Para estos, descargamos la fuente a pedido cuando se elige en el selector de fuente desplegable. Las vistas previas en el menú desplegable son imágenes de muestra de cómo se ve la fuente. Esto nos evita tener que descargar 10 o más archivos de fuentes adicionales.
Soporte heredado
Un día, CSS-Tricks me sorprendió con un artículo sobre “Cómo usar Favicon en 2021”. Estábamos usando todos los tamaños de íconos táctiles del mundo: el artículo me hizo reevaluar lo que realmente necesitamos y me mostró que a veces lo que era cierto hace unos años ya no se necesita. Según el artículo, limitamos nuestras listas de íconos favoritos y táctiles a las versiones recomendadas.
De manera similar, también convertimos una fuente que teníamos solo como una versión WOFF a WOFF2 , que es mucho más pequeña, y decidimos proporcionar WOFF2 para las fuentes (con WOFF restante como respaldo). Y purgamos las directivas CSS que ya no son necesarias.
Carga perezosa y bajo demanda
Varias métricas se centran en el tiempo después del cual los usuarios pueden interactuar con la página. La lógica dicta que tener menos elementos para cargar significa que se llegará antes a este punto. Para dar cuenta de esto, es importante preguntarse qué partes de la página son esenciales y cuáles el usuario solo necesitará más adelante. Pasamos por mucho debate y prueba y error sobre esto.
La cascada de actividad de la red ayudó mucho aquí, pero también lo hizo pensar en los flujos de usuarios. Por ejemplo, la imagen del producto ampliada se puede cargar la primera vez que un usuario interactúa con la imagen del producto, y las imágenes en el pie de página generalmente no se muestran en la parte superior de la página y se pueden cargar más tarde. Si le preocupan las ralentizaciones, aún puede trabajar con la obtención previa de recursos.
Una cosa que notamos desde el principio fue el gran impacto del cliente de chat. Solo tenía más de 500 KB de JavaScript, y aunque lamentablemente ya no tengo un gráfico, también tardó en cargar. Aunque JavaScript estaba configurado para cargarse de forma asincrónica, Google lo estaba incluyendo en las mediciones de tiempo de interacción.
No pudimos rastrear completamente por qué sucedió esto, pero entre esto y su gran tamaño, comenzamos a buscar alternativas, en lugar de tratar de arreglar algo sobre lo que teníamos un control limitado. Convencimos a jewellerybox para que probara un widget de chat de código abierto autohospedado , que nos da más control sobre cómo se carga y que también es mucho más pequeño. Para mejorarlo aún más, inicialmente solo cargamos el icono del chat; el resto se carga cuando haces clic para abrirlo.
El carrusel invisible de terceros
Jewellerybox quería probar un servicio de terceros que utiliza IA para mejorar la personalización del producto en los carruseles de varias páginas. Decidimos llamar a su API desde el back-end para esto, de modo que tuviéramos más control sobre lo que se carga (sin grandes dependencias de JavaScript) y cuánto tiempo esperamos una respuesta de su servicio (con algunas alternativas definidas). Debido a esto, los carruseles se cargan de la misma manera que los no personalizados y también se pueden almacenar en caché con una clave de caché única.
Sin embargo, existe un inconveniente: esto significa que la representación de la página inicial en el lado del servidor podría ser más lenta a menos que se almacene en caché. Por esta razón, actualmente estamos trabajando en formas alternativas de inyectar los resultados después de que la página se haya cargado y al principio representar un marcador de posición.
Segundo: Optimización de JavaScript: una batalla cuesta arriba contra enemigos externos
El carrusel nos lleva a la segunda gran área en la que nos enfocamos: JavaScript. Hicimos una auditoría del JavaScript que teníamos, y la mayoría es de bibliotecas para diferentes tareas, con muy poco código personalizado. Optimizamos el código que habíamos escrito nosotros mismos, pero obviamente no hay mucho que pueda hacer si es solo una fracción de su código general: las grandes ganancias se encuentran en las bibliotecas.
Optimizar cosas en las bibliotecas o sacar partes que no necesita es, con toda probabilidad, una tontería. Realmente no sabe por qué algunas partes están allí, y nunca podrá actualizar la biblioteca nuevamente sin mucho trabajo manual. Con eso en mente, dimos un paso atrás y observamos qué bibliotecas usamos y para qué las necesitamos , e investigamos para cada una si existe una alternativa más pequeña o más rápida que se ajuste a nuestras necesidades.
¡En varios casos, lo hubo! Por ejemplo, decidimos reemplazar la biblioteca deslizante Slick con GliderJS, que tiene menos funciones pero todas las que necesitamos, además es más rápido de cargar y tiene soporte CSS más moderno. Además, sacamos muchas de las bibliotecas independientes del archivo principal de JavaScript y comenzamos a cargarlas a pedido.
Debido a que estamos usando Bootstrap 4, todavía estamos incluyendo jQuery para el proyecto, pero estamos trabajando para reemplazar todo con implementaciones nativas. Para Bootstrap en sí, hay una versión bootstrap.native en GitHub sin la dependencia de jQuery que usamos ahora. Es más pequeño en tamaño y funciona más rápido. Además, generamos dos versiones de nuestro archivo JavaScript principal: una sin polyfills y otra con ellos incluidos, y cambiamos la versión con ellos cuando el navegador los necesita, lo que nos permite ofrecer una versión principal optimizada para la mayoría de las personas. Probamos un servicio de "polyfill-on-demand", pero el rendimiento no cumplió con nuestras expectativas.
Una última cosa sobre el tema de jQuery. Inicialmente, lo cargamos desde nuestro servidor. Vimos mejoras de rendimiento en nuestro sistema de prueba cuando lo cargamos a través de Google CDN, pero Page Speed Insights se quejó del rendimiento (me pregunto quién podría resolver eso), así que volvimos a probarlo nosotros mismos y en producción fue más rápido debido a la CDN que usamos.
Lección aprendida : un entorno de prueba no es un entorno de producción, y las soluciones para uno pueden no ser válidas para el otro.
Tercero: imágenes: formatos, tamaños y todo ese jazz
Las imágenes son una gran parte de lo que hace una tienda en línea. Una página suele tener varias decenas de imágenes, incluso antes de contar las diferentes versiones para diferentes dispositivos. El sitio web de joyeros existe desde hace casi 10 años, y muchos productos han estado disponibles durante la mayor parte de ese tiempo, por lo que las imágenes originales de los productos no son uniformes en tamaño y estilo, y la cantidad de fotografías de productos también puede variar.
Idealmente, nos gustaría ofrecer imágenes receptivas para diferentes tamaños de vista y densidades de visualización en formatos modernos, pero cualquier cambio en los requisitos significaría mucho trabajo de conversión por hacer. Debido a esto, actualmente usamos un tamaño optimizado de imágenes de productos, pero no tenemos imágenes receptivas para ellos. Actualizar eso está en la hoja de ruta, pero no es trivial. Las páginas de contenido ofrecen más flexibilidad, y allí generamos y usamos diferentes tamaños e incluimos formatos WebP y fallback.
Tener tantas imágenes agrega mucho peso a la carga útil inicial. Entonces, cuándo y cómo cargar imágenes se convirtió en un gran tema. La carga diferida suena como la solución, pero si se aplica universalmente, puede ralentizar las imágenes inicialmente visibles, en lugar de cargarlas directamente (o al menos así lo siente el usuario). Por esta razón, optamos por una combinación de carga directa de los primeros y carga diferida del resto, usando una combinación de carga diferida nativa y un script.
Para el logotipo del sitio web, usamos un archivo SVG, para el cual obtuvimos una versión inicial del cliente. El logotipo es una fuente intrincada en la que faltan partes de las letras, ya que estarían en una impresión imperfecta hecha a mano. En tamaños grandes, debe mostrar los detalles, pero en el sitio web nunca lo usamos por encima de 150 por 30 píxeles. El archivo original tenía un tamaño de 192 KB, no enorme pero tampoco muy pequeño. Decidimos jugar con el SVG y disminuir los detalles en él, y terminamos con una versión descomprimida de 40 KB de tamaño. No hay diferencia visual en los tamaños de pantalla que usamos.
Por último, pero definitivamente no menos importante: CSS
CSS crítico
CSS ocupa un lugar destacado en el Informe de experiencia del usuario de Chrome (CrUX) de Google y también aparece en gran medida en el informe y las recomendaciones de Google Page Speed Insights. Una de las primeras cosas que hicimos fue definir un CSS crítico, que cargamos directamente en el HTML para que esté disponible para el navegador lo antes posible: esta es su arma principal para luchar contra los cambios de diseño de contenido (CLS). Optamos por una combinación de extracción automatizada del CSS crítico basado en una página prototipo y un mecanismo con el que podemos definir los nombres de las clases que se extraerán (incluidas todas las subreglas). Hacemos esto por separado para estilos generales, estilos de página de productos y estilos de categoría que se agregan en los tipos de página respectivos.
Algo que aprendimos de esto y que causó algunos errores en el medio es que debemos tener cuidado de que esto no cambie el orden de CSS. Entre diferentes personas que escriben el código, alguien que agrega una anulación más adelante en el archivo y una herramienta automática que extrae cosas, puede complicarse.
Dimensiones explícitas contra CLS
Para mí, CLS es algo que Google sacó de su sombrero, y ahora todos debemos lidiar con eso y envolver nuestras cabezas colectivas a su alrededor. Mientras que antes, simplemente podíamos dejar que los contenedores obtuvieran su tamaño de los elementos dentro de ellos, ahora la carga de esos elementos puede alterar el tamaño de la caja. Con eso en mente, usamos la pestaña "Rendimiento" en las Herramientas para desarrolladores y el súper útil Generador de GIF de cambio de diseño para ver qué elementos están causando CLS. A partir de ahí, observamos no solo los elementos en sí, sino también sus padres y analizamos las propiedades CSS que tendrían un impacto en el diseño. A veces tuvimos suerte, por ejemplo, el logotipo solo necesitaba un tamaño explícito establecido en el dispositivo móvil para evitar un cambio de diseño, pero otras veces, la lucha fue real.
Consejo profesional: a veces, un cambio no es causado por el elemento aparente, sino por el elemento que lo precede. Para identificar a los posibles culpables, concéntrese en las propiedades que cambian de tamaño y espacio. La pregunta básica que debe hacerse es: ¿Qué podría causar que este bloque se mueva?
Debido a que hay tantas imágenes en la página, lograr que se comporten correctamente con CLS también nos supuso un poco de trabajo. Barry Pollard nos lo recuerda acertadamente en su artículo, "Configurar la altura y el ancho de las imágenes es importante de nuevo". Pasamos mucho tiempo averiguando los valores correctos de ancho y alto (más las relaciones de aspecto) para nuestras imágenes en cada caso para agregarlas nuevamente al HTML. Como resultado, ya no hay cambio de diseño para las imágenes porque el navegador obtiene la información antes.
El caso de la misteriosa partitura CLS
Después de eliminar muchos de los grandes problemas de CLS cerca de la parte superior de la página, nos encontramos con un obstáculo. A veces (no siempre) al mirar Page Speed o Lighthouse, obtuvimos una puntuación CLS de más de 0,3, pero nunca en la pestaña "Rendimiento". El generador de GIF de desplazamiento de diseño a veces lo mostraba, pero parecía que todo el contenedor de la página se estaba moviendo .
Con la aceleración de la red y la CPU habilitada, ¡finalmente lo vimos en las capturas de pantalla! El encabezado en el móvil creció 2 píxeles de altura debido a los elementos que contenía. Debido a que el encabezado tiene una altura fija en el móvil de todos modos, optamos por la solución simple y le agregamos una altura explícita: caso cerrado. Pero nos costó muchos nervios y muestra que las herramientas aquí todavía son muy imprecisas.
Esto no está funcionando, ¡rehagámoslo!
Como todos sabemos, los puntajes móviles son mucho más duros para Page Speed que para computadoras de escritorio, y un área en la que fueron particularmente malos para nosotros fue en las páginas de productos. La puntuación de CLS estaba por las nubes, y la página también tenía problemas de rendimiento (varios carruseles, pestañas y elementos no almacenables en caché harán eso). Para empeorar las cosas, el diseño de la página significaba que parte de la información se mezclaba o se agregaba dos veces.
En el escritorio, básicamente tenemos dos columnas para el contenido:
- Columna A : el carrusel de fotos del producto, a veces seguido de citas de bloggers, seguido de un diseño con pestañas con información del producto.
- Columna B : El nombre del producto, el precio, la descripción y el botón “añadir a la cesta”.
- Fila C : El carrusel de productos de productos similares.
Sin embargo, en dispositivos móviles, el carrusel de fotos del producto debía aparecer primero, luego la columna B, luego el diseño con pestañas de la columna A. Debido a esto, cierta información se duplicaba en el HTML, controlada por display: none
, y el orden se estaba cambiado con la propiedad flex: order
. Definitivamente funciona, pero no es bueno para los puntajes de CLS porque básicamente todo necesita ser reordenado.
Me decidí por un experimento simple en CodePen: ¿podría lograr el mismo diseño básico de cuadros en el escritorio y en el móvil al repensar el HTML y usar display: grid
en lugar de flexbox, y eso me permitiría simplemente reorganizar las áreas de la cuadrícula según sea necesario? En pocas palabras, funcionó y resolvió CLS, y tiene el beneficio adicional de que el nombre del producto ahora aparece mucho antes en el HTML que antes: ¡una ganancia adicional de SEO!
Hackear un carrusel para CLS
La palabra "carrusel" ya ha aparecido varias veces, y por una buena razón. No solo cambiamos la biblioteca de carrusel que usamos (y cambiamos el comportamiento de carga de las imágenes en ella), también tuvimos que lidiar con CLS porque tenemos varias páginas en las que el carrusel está arriba del pliegue y, por lo tanto, podría tener un gran impacto en las puntuaciones de velocidad.
Comenzamos cargando el carrusel más tarde para disminuir el tiempo de interacción , pero eso provocó un retraso visible hasta que se activó el JavaScript y las diapositivas pasaron de estar una debajo de la otra a estar en una fila. Probamos muchas formas de escribir el CSS para evitar que esto sucediera y mantener todo en una fila, incluso ocultar todo el carrusel hasta que terminara de cargarse. Nada nos dio el tipo de solución que nos hubiera gustado ver al visitar una tienda como usuario.
Perdón por esta breve diatriba, pero en verdad, los carruseles de productos y categorías son la tormenta perfecta de elementos flexibles en una tienda receptiva: es posible que las imágenes no tengan una altura universal, los nombres de los productos pueden abarcar varias líneas y es posible que tenga o no etiquetas. Básicamente, se reduce a esto: no es posible una altura fija para la fila, y tampoco se sabe realmente el ancho. Tiempos divertidos.
Al final, decidimos configurar todas las diapositivas (excepto la primera) para que sean visibles visibility: hidden
hasta que el carrusel haya terminado de cargarse, momento en el que agregamos una clase al carrusel para cambiar todas las diapositivas para que estén visibles nuevamente . Esto resuelve el problema de que ocupa altura adicional al principio.
Además, configuramos flex-shrink: 0
y flex-base: 340px
para las diapositivas en un flexbox sin envoltura inicialmente. Esto hace que estén en una sola línea y da un ancho inicial aproximado para las diapositivas. Con ese acertijo resuelto, y sí, fue un dolor de cabeza tan grande como parece, agregamos algunas correcciones para dejar espacio para que caigan los puntos y las flechas. Con eso en su lugar, ¡ya casi no hay CLS para los carruseles!
La retrospectiva es 20 ⁄ 20
Al final, fueron muchos pequeños cambios durante varios meses los que mejoraron nuestros puntajes, y no hemos terminado. Trabajamos principalmente con dos personas en las mejoras del front-end, mientras que el resto del equipo se enfocó en mejorar el back-end. Si bien probablemente fue un poco más lento de esta manera, aseguró que no hubiera superposición y que las diferencias en las puntuaciones pudieran atribuirse claramente. Algunos recursos que ayudaron mucho fueron los excelentes artículos aquí en Smashing Magazine sobre las propias mejoras de la revista.
En algún momento, las cosas que debe probar se vuelven no obvias porque no cree que deban marcar una gran diferencia, pero un tiempo después se da cuenta de que sí lo hacen. Más que eso, lo que este proyecto nos enseñó nuevamente es cuán importante es tener en cuenta el rendimiento y las métricas desde el principio , desde la visualización del diseño y la codificación del prototipo hasta la implementación en las plantillas. Las pequeñas cosas que se descuidan al principio pueden convertirse en enormes montañas que tienes que escalar más tarde para deshacerlas.
Estos son algunos de los aspectos clave que aprendimos:
- Optimizar JavaScript no es tan efectivo como cargarlo a pedido;
- La optimización de CSS parece ganar más puntos que la optimización de JavaScript;
- Escriba clases de CSS con CLS y extracción de CSS crítico en mente;
- Las herramientas para encontrar problemas de CLS aún no son perfectas. Piense fuera de la caja y verifique varias herramientas;
- Evalúe cada servicio de terceros que integre en cuanto al tamaño del archivo y el tiempo de rendimiento. Si es posible, rechace la integración de cualquier cosa que pueda ralentizar todo;
- Vuelva a probar su página regularmente para detectar cambios en CrUX (y especialmente en CLS);
- Verifique regularmente si todas sus entradas de soporte heredadas aún son necesarias.
Todavía tenemos cosas en nuestra lista de mejoras para hacer:
- Todavía tenemos mucho CSS sin usar en el archivo principal que podría eliminarse;
- Nos gustaría eliminar jQuery por completo. Esto significará reescribir partes de nuestro código, especialmente en el área de pago;
- Es necesario realizar más experimentos sobre cómo incluir los controles deslizantes externos;
- Nuestros puntajes de puntos móviles podrían ser mejores. Se necesitará más trabajo especialmente para dispositivos móviles;
- Se deben agregar imágenes receptivas para todas las imágenes de productos;
- Verificaremos las páginas de contenido específicamente para las mejoras que puedan necesitar, especialmente en torno a CLS;
- Los elementos que usan el complemento de colapso de Bootstrap se reemplazarán con la etiqueta de
details
HTML nativa; - El tamaño del DOM debe reducirse;
- Integraremos un servicio de terceros para obtener mejores y más rápidos resultados de búsqueda. Esto vendrá con una gran dependencia de JavaScript que necesitaremos integrar;
- Trabajaremos para mejorar la accesibilidad mediante la búsqueda de herramientas automatizadas y la ejecución de algunas pruebas con lectores de pantalla y navegación por teclado nosotros mismos.
Más recursos
- “Sugerencias y accesos directos para la depuración de DevTools (Chrome, Firefox, Edge)”, Vitaly Friedman, Smashing Magazine
- "Algunas publicaciones de blog sobre rendimiento que he marcado y leído últimamente", Chris Coyier, CSS-Tricks
- "Una guía detallada para medir los datos vitales básicos de la web", Barry Pollard, Smashing Magazine
- "De CSS semántico a Tailwind: refactorización de la base de código de la interfaz de usuario de Netlify", Charlie Gerard y Leslie Cohn-Wein, Netlify
- "Herramientas de auditoría de CSS", Iris Lješnjanin, Smashing Magazine
- "Cosas que puedes hacer con CSS hoy", Andy Bell, Smashing Magazine
- "Cómo mejorar el rendimiento de CSS", Milica Mihajlija, Calibre
- “La brecha de desigualdad del rendimiento móvil, 2021”, Alex Russell
- "Optimización máxima de la carga de imágenes para la web en 2021", Malte Ubl
- “El elemento
<img>
humilde y los elementos fundamentales de la web”, Addy Osmani, Smashing Magazine