Lista de verificación de velocidad web 2021

Hagamos del 2021... un año rápido. Presentamos, en español, una lista de verificación para la optimización de la velocidad del frontend de los sitios web. Contiene casi todo lo que necesitas saber para asegurar una experiencia de usuario rápida hoy en día, desde métricas, herramientas hasta técnicas de desarrollo.
Esta lista de verificación es una traducción del Front-End Performance Checklist 2021. Agradecimientos a Smashing Magazine.
Contenido del artículo:
- Preparación: Planificación y métricas
- Establecer objetivos realistas
- Definición del entorno de desarrollo
- Optimización de archivos
- Optimización de la construcción
- Optimización de la carga
- Red y HTTP/2
- Pruebas y monitoreo
- Victorias rápidas
Preparación: Planificación y métricas
-
Crea una "cultura de rendimiento", que apoye la velocidad del sitio web.
La velocidad del sitio web no puede ser sostenible a largo plazo sin inversión. Estudia las quejas comunes que llegan al soporte al cliente y descubre cómo el aumento de la velocidad puede ayudar a mitigar algunos de estos problemas. Crea un estudio de caso con datos reales y métricas comerciales, adaptado a tu empresa. Planifica el flujo de carga del sitio y posibles compromisos desde el diseño.
-
Sé un 20% más rápido que tu competidor más veloz.
Reúne datos sobre los dispositivos que utilizan los visitantes de tu sitio web. Prioriza dispositivos reales sobre simulaciones. Elige un móvil Moto G4/G5 Plus; un dispositivo Samsung de gama media (Galaxy A50, S8); un buen dispositivo de gama media como Nexus 5X, Xiaomi Mi A3 o Xiaomi Redmi Note 7 y un dispositivo lento como Alcatel 1X o Cubot X19. Alternativamente, puedes emular un sistema operativo móvil en una computadora probando a velocidad de red limitada (por ejemplo, 300 ms RTT, 1,6 Mb/s descarga, 0,8 Mb/s subida) con CPU limitada (5x ralentización). Luego cambia a 3G común, 4G lento (por ejemplo, 170 ms RTT, 9 Mb/s descarga, 9 Mb/s subida) y Wi-Fi. Recoge datos, construye una tabla, resta el 20% de los resultados y establece tus objetivos ("performance budgets", límites de velocidad).
-
Elige las métricas correctas.
No todas las métricas tienen el mismo valor desde el punto de vista de la optimización. Estudia cuáles métricas importan más: generalmente estarán relacionadas con la rapidez con la que se comienzan a renderizar los píxeles más importantes y cuán rápida es la respuesta de entrada. Enfócate en el tiempo de carga de la página según las prioridades de tus visitantes. Usualmente, importa el tiempo hasta la interactividad (Time To Interactive – TTI), retraso en la primera entrada (First Input Delay – FID), tiempo de renderizado del elemento "hero", la mayor pintura con contenido (Largest Contentful Paint – LCP), tiempo total de bloqueo (Total Blocking Time – TBT) y desplazamiento acumulativo del diseño (Cumulative Layout Shift – CLS). No tanto en: Primera Pintura Significativa (First Meaningful Paint).
-
Configura perfiles de prueba: "limpio" y "de cliente".
Desactiva los programas antivirus y las tareas intensivas de CPU en segundo plano, detén las transferencias de datos en segundo plano y prueba con un perfil de usuario "limpio" sin extensiones de navegador, para evitar distorsionar los resultados. Estudia qué extensiones utilizan tus clientes y prueba también un perfil especial "de cliente".
-
Comparte la Lista de verificación de velocidad web con tus colegas.
Asegúrate de que cada miembro del equipo conozca esta Lista de verificación de velocidad web. Cada decisión afecta el rendimiento y ayudará significativamente a tu proyecto si la propiedad se distribuye entre todo el equipo. Además, mapea las decisiones de diseño y contrástalas con el presupuesto de rendimiento.
Establecer objetivos realistas
-
Tiempo de respuesta de 100 milisegundos, 60 fotogramas por segundo.
Cada fotograma de animación debe ejecutarse en 16 milisegundos — idealmente en 10 milisegundos, logrando los deseados 60 fotogramas por segundo (1 segundo ÷ 60 = 16,6 milisegundos). Sé optimista y usa el tiempo de inactividad con sabiduría; para tareas intensivas como las animaciones, es mejor no hacer nada más en la página. Allí donde no sea posible, hacer solo lo absolutamente mínimo. La latencia de entrada estimada debe ser menor de 50 ms. Usa el tiempo de inactividad con el enfoque Idle Until Urgent.
-
LCP < 2,5 segundos; FID < 100 ms; CLS < 0,1; TTI < 5 segundos en 3G.
Considerando un dispositivo base un móvil Android de alrededor de 4 mil pesos en una red 3G lenta, emulado a una velocidad de transferencia de 400 ms RTT y 400 kB/s, apunta a un tiempo hasta la interactividad (TTI) < 5 segundos y visitas repetidas bajo 2–3 segundos. Apunta a un renderizado del contenido más grande < 2,5 segundos y minimiza el tiempo total de bloqueo (TBT) y el desplazamiento acumulativo del diseño (CLS). Esfuérzate por reducir estos valores al mínimo.
-
Tamaño máximo de archivo < 170 kB.
Los primeros 14–16 kB de código HTML son críticos — es la única parte entregada en el primer paquete transmitido por la red ("primer viaje de ida y vuelta"). Para lograr los objetivos establecidos, trabaja con archivos de un tamaño máximo gzipado de 170 kB (0,7 – 0,8 MB descomprimidos). Asegúrate de que tus límites de velocidad se ajusten a las condiciones de la red y las restricciones de hardware.
Definición del entorno de desarrollo
-
Elige y configura bien tus herramientas de construcción.
No te obsesiones demasiado con si es una herramienta "cool" o no. Si obtienes resultados rápidamente y no tienes problemas para mantener tu proceso de creación, entonces está bien. Las excepciones pueden ser Webpack o Parcel, que proporcionan técnicas de optimización útiles como la división de código (code-splitting). Si aún no utilizas estas técnicas, entonces consulta el code-splitting mencionado y el tree-shaking.
-
Usa la mejora progresiva por defecto (progressive enhancement).
Primero diseña y crea una interfaz básica para que el sitio web cumpla con su función esencial. Luego mejora la interfaz con funciones avanzadas para diferentes navegadores, creando una interfaz resistente y estable para diversos usuarios con diferentes dispositivos. Si tu sitio web funciona rápidamente en un dispositivo lento, con una mala pantalla y en un navegador deficiente en una red no óptima, entonces funcionará aún más rápido en un dispositivo rápido, con un buen navegador y en una red razonablemente rápida.
-
Establece un alto estándar de rendimiento.
JavaScript implica los mayores costos para la experiencia del usuario. Con un límite de 170 kB, que ya incluye datos y rutas críticas – HTML / CSS / JavaScript, enrutador, gestión de estado, herramientas, interfaz y aplicaciones – examina cuidadosamente los costos de tiempo de transferencia de red, análisis, compilación y los costos de tiempo de ejecución del framework.
-
Evalúa cada framework y cada dependencia.
No todos los proyectos necesitan un framework, no todas las aplicaciones de una sola página (SPA) necesitan cargar un framework. Elige con cuidado; evalúa JS de terceros examinando las características, accesibilidad, estabilidad, velocidad, ecosistemas de paquetes, curva de aprendizaje, documentación, herramientas, registros, equipo, compatibilidad y seguridad. Next.js (React), Gatsby (React), Vuepress (Vue) y Preact CLI proporcionan valores predeterminados decentes para cargas rápidas en hardware móvil promedio.
-
Elige sabiamente: React, Vue, Angular, Ember y compañía.
Asegúrate de que el framework de tu elección proporcione renderizado del lado del servidor (SSR) o prerenderizado. Antes de decidirte, mide en dispositivos móviles los tiempos de renderizado tanto en el servidor como en el cliente. Es importante conocer los "tornillos y tuercas" del framework en el que vas a confiar. Consulta el patrón de diseño PRPL y la arquitectura App Shell. Buenas opciones son Preact, Inferno, Vue, Svelte, Alpine, Polymer.
-
Optimiza el rendimiento de tus API.
API puede convertirse fácilmente en un cuello de botella cuando varias servicios acceden a ella simultáneamente. Considera la posibilidad de utilizar el lenguaje GraphQL, que te permite ejecutar consultas sobre un sistema de tipos que creas sobre tus datos. A diferencia de REST, GraphQL puede obtener todos los datos en una consulta sin descargar demasiados o pocos, lo que a menudo ocurre en arquitecturas REST.
-
¿Probarías las tecnologías Google AMP o Facebook Instant Articles?
Incluso sin estas tecnologías, puedes lograr un buen rendimiento, pero AMP ofrece una base de rendimiento muy sólida y una CDN global. Instant Articles te ayudarán a ganar visibilidad en Facebook y a cargar hasta 4 veces más rápido que los sitios móviles convencionales.
-
Elige sabiamente tu CDN.
Considera cuán dependiente eres de los datos dinámicos. Puedes generar al menos parte de tu contenido estáticamente, subirlo a una CDN y así evitar consultas innecesarias a la base de datos (JAMStack). Verifica que la CDN realice compresión de contenido y conversión de imágenes (por ejemplo, optimización y cambio de tamaño o formato) y que soporte workers del lado del servidor.
Optimización de archivos
-
Usa Brotli para la compresión.
Brotli es un nuevo formato de datos sin pérdida, compatible con todos los navegadores modernos. Es más eficiente que GZip y Deflate. La compresión es muy lenta, pero la descompresión es rápida. Precomprime los assets estáticos utilizando Brotli y Gzip en el nivel más alto, comprime HTML dinámicamente en tiempo de ejecución usando Brotli (nivel 1-4). Verifica también el soporte de Brotli en tu CDN. Asegúrate de que el servidor maneje la "negociación de contenido" para Brotli o Gzip correctamente.
-
Usa imágenes responsivas, AVIF y WebP.
Siempre que sea posible, usa imágenes responsivas con las propiedades
srcset, sizes, <picture> y image-set.Usa los formatos AVIF y WebP con<picture>y JPEG/PNG como respaldo o detecta el soporte mediante el encabezado Accept. Nota: con WebP reduces el peso de los datos, pero con JPEG puedes mejorar la velocidad percibida gracias a la característica de "renderizado progresivo". -
¿Están las imágenes correctamente optimizadas?
Usa mozJPEG para la compresión de JPEG, SVGO para la compresión de SVG, Pingo para PNG o Squoosh para todos ellos (incluido AVIF). Para verificar la efectividad de tu marcado responsivo, puedes usar la herramienta imaging-heap. Para imágenes críticas, usa JPEG progresivo y difumina las partes innecesarias (aplicando desenfoque gaussiano) y elimina el contraste (puedes restablecerlo usando filtros CSS). Asegúrate de que los atributos width y height estén establecidos para todas tus imágenes. Añade compresión automática de imágenes a tus pull requests y explora el lazy loading de imágenes menos críticas.
-
¿Están los videos correctamente optimizados?
En lugar de GIFs animados, usa ya sea WebP animado (y un GIF como respaldo) o inserta bucles con video HTML5 en línea. Asegúrate de que tus archivos MP4 están procesados con codificación multipass, difuminados con el efecto "frei0r iirblur" (si está disponible), los metadatos moov atom se mueven a la cabecera del archivo, y tu servidor acepta Byte serving. Siempre que sea posible, usa video en formato AV1, pero proporciona también respaldo para formatos más antiguos. Ajusta las dimensiones de los videos y mediante la entrega adaptativa de medios proporciona contenido a los visitantes que puedan reproducir en sus dispositivos sin retrasos.
-
¿Están optimizadas las fuentes?
Configura correctamente el subsetting de las fuentes. Prioriza WOFF2 y usa WOFF como respaldo. Muestra el contenido inmediatamente con una fuente de respaldo, carga la fuente personalizada de forma asíncrona y luego cambia la fuente. Solución ideal: renderizado en dos etapas, primero con un superconjunto pequeño y el resto se carga asíncronamente más tarde. Precarga (preload) 1-2 fuentes de cada familia. Evita usar local() en la declaración de la fuente, pero considera usar fuentes instaladas en el sistema operativo. No olvides usar font-display:optional y utiliza eventos de carga de fuentes para el re-renderizado. Usa las métricas Web Font Reflow Count y Time To Real Italics.
Optimización de la construcción
-
Configura correctamente las prioridades.
Revisa todos tus recursos (JavaScript, imágenes, fuentes, scripts de terceros, módulos "costosos" en la página) y agrúpalos. Define la experiencia básica (contenido básico completamente accesible para navegadores más antiguos), experiencia mejorada (enriquecida y completa para navegadores modernos) y complementos (recursos que no son estrictamente necesarios y que pueden cargarse de manera diferida).
-
Usa módulos JavaScript nativos en producción.
En navegadores más antiguos, apoya la experiencia básica, solo completa en navegadores modernos. Para cargar JavaScript usa ES2017+
<script type="module">. Los navegadores modernos interpretan el script como un módulo JavaScript y lo ejecutan según lo esperado. Los navegadores más antiguos lo ignoran. -
Ejecutar JavaScript es costoso, así que domínalo.
En aplicaciones SPA, necesitas algo de tiempo para inicializar la aplicación antes de poder renderizar la página. Busca módulos y técnicas para acelerar el tiempo de renderizado inicial, como progressive hydration y la importación en la interacción (en móviles más antiguos, los tiempos son 2-5 veces más altos).
-
Usa tree-shaking, scope hoisting y code-splitting para reducir la carga.
Tree-shaking es un método que usa solo el código realmente utilizado durante la construcción. Code-splitting divide el código en "bloques" que se cargan bajo demanda. Scope hoisting detecta dónde se puede fusionar la cadena de importaciones y convertirla en una función embebida manteniendo la funcionalidad (por ejemplo, con Webpack). Usa granular chunking y mueve parte del renderizado del cliente al servidor. Define la división monitoreando qué bloques CSS/JS se usan y cuáles no. Considera también el code-splitting a nivel de paquetes.
-
¿Puedes mover JavaScript a un Web Worker o WebAssembly?
A medida que el código se desarrolla, los puntos débiles del rendimiento de la interfaz de usuario comienzan a aparecer. Resulta que las operaciones con el DOM se ejecutan junto a tu JS en el hilo principal. Considera mover estas operaciones costosas a procesos en segundo plano que se ejecutan en un hilo diferente usando webworkers. Un caso típico: precarga de datos para PWA. Considera mover tareas computacionalmente intensivas a WebAssembly, que funciona mejor para aplicaciones web intensivas, como los juegos.
-
Envía código para navegadores más antiguos solo a estos navegadores más antiguos.
Usa babel-preset-env para transpilar funciones ES2017+ no soportadas por los navegadores modernos que soportas. Luego configura dos versiones de construcción, una para navegadores modernos y otra para navegadores más antiguos.
Para lodash, usa babel-plugin-lodash, que carga solo los módulos que usas en el código fuente. Cambia el require general de lodash y selecciona solo los utilizados, evitando la duplicación de código. Usa
<link rel="modulepreloak">para iniciar la carga temprana (de alta prioridad) de módulos. -
Identifica y reescribe código antiguo (legacy) con "desacoplamiento incremental".
Revisa las dependencias del proyecto y evalúa cuánto tiempo tomaría refactorizar o reescribir el código antiguo. Primero establece métricas que monitoreen si la proporción de llamadas al código legacy permanece igual o disminuye. La proporción no debe aumentar. Establece condiciones en el equipo que no toleren el uso de bibliotecas adicionales y asegúrate de que CI siempre notifique a los desarrolladores durante el pull request.
-
Identifica y elimina CSS/JavaScript no utilizados.
La cobertura de CSS y JavaScript en el navegador Chrome te permite saber qué código se ha ejecutado/usado y cuál no. Una vez que asegures el código no utilizado, encuentra estos módulos y añade carga diferida usando import(). Después de la edición, repite la prueba de cobertura de código y verifica que ahora se envíe menos código en la primera carga. Usa Puppeteer para recopilar automáticamente los resultados de la cobertura de código.
-
Reduce el tamaño de las dependencias en JavaScript.
Hay una gran probabilidad de que tengas bibliotecas JavaScript completas en tus proyectos, pero realmente uses solo una fracción del código. Considera usar el automatizado webpack-libs-optimizations, que elimina métodos no utilizados y polyfills durante el proceso de construcción. Añade al flujo de trabajo habitual un control de paquetes. Bundlephobia ayuda a cuantificar el impacto en el rendimiento al agregar paquetes NPM individuales al proyecto. Size-limit amplía el control clásico del tamaño del paquete con la duración del tiempo de ejecución en JavaScript. Skypack puede usarse como fuente de paquetes enfocados en la calidad y el rendimiento y administrados por miembros individuales de la comunidad.
-
¿Estás usando prefetch predictivo para fragmentos de código JavaScript?
Usa tu experiencia e intuición para determinar cuándo precargarás tu JS. Guess.js incluye herramientas que usan datos de Google Analytics para determinar qué página probablemente visitará el usuario a continuación. Considera Quicklink, Instant.page y DNStradamus. Nota: Puede que estés instruyendo al navegador para que descargue datos innecesarios y precargue páginas innecesarias. Recomendamos ser cautelosos con el número de solicitudes precargadas.
-
Optimiza para tus motores de JavaScript objetivo.
Usa script streaming para scripts monolíticos, de modo que puedan ser analizados inmediatamente después de comenzar la descarga en un hilo de fondo separado. También aprovecha code caching del motor V8 separando las bibliotecas del código que las utiliza. Considera también estrategias de optimización JIT para Baseline Interpret en el navegador Firefox.
-
Encuentra una manera de combinar el renderizado en el lado del cliente y en el servidor.
El objetivo suele ser encontrar un equilibrio óptimo entre el renderizado del lado del cliente y del lado del servidor. Considera el prerenderizado si tus páginas no cambian con demasiada frecuencia y, si es posible, pospón la inicialización de los frameworks. Transmite fragmentos (chunks) de HTML mediante renderizado del lado del servidor e hidrata solo cuando se visualice, interactúe o durante la inactividad, para obtener lo mejor de ambos mundos. (Streaming Server-Side Rendering With Progressive Hydration).
-
Considera microoptimización y inicio progresivo.
Usa renderizado del lado del servidor para un rápido "primer renderizado significativo" (FMP), pero incluye también JS mínimo para mantener el "tiempo hasta la interactividad" (TTI) cerca del "primer renderizado significativo". Luego, ya sea bajo demanda o cuando el tiempo lo permita, ejecuta las partes no esenciales de la aplicación. Siempre divide la ejecución de funciones en tareas asíncronas. Si es posible, usa requestIdleCallback.
-
Aloja tus propios recursos de terceros.
Usar una CDN pública no es automáticamente más rápido. Aunque dos sitios web referencien exactamente la misma URL de recurso de terceros, el código se descarga nuevamente para cada dominio. La caché está aislada por dominio. Los recursos propios tienen más probabilidades de permanecer en caché que los recursos de terceros. El alojamiento propio es más confiable, seguro y eficiente.
-
Limita el impacto de los scripts de terceros.
Muy a menudo, un script de terceros causa el "largo tail" y arruina la velocidad. Considera usar service workers para descargar recursos con un límite de tiempo. Configura Content Security Policy (CSP) para limitar el impacto de los scripts de terceros, por ejemplo, deshabilitando la descarga de audio o video. Inserta scripts a través de un iframe, así los scripts no tendrán acceso al DOM. Para pruebas de carga de scripts, explora las resúmenes en la pestaña Performance (DevTools). Carga scripts de terceros solo después de que la aplicación esté cargada. Concéntrate en fragmentos de código que eviten el parpadeo del contenido antes de cargar el script.
-
Configura correctamente las cabeceras de caché HTTP.
Verifica que expires, cache-control, max-age y otras cabeceras de caché HTTP estén configuradas correctamente. En general, los recursos deben ser cacheables o bien por un tiempo muy corto (si es probable que cambien) o para siempre (si son estáticos).
Usa cache-control: immutable para evitar la revalidación. Verifica que no estás enviando cabeceras innecesarias (por ejemplo, x-powered-by, pragma, x-ua-compatible, expires). Aprovecha el cero RTT para la representación repetida a través de stale-while-revalidate.
Optimización de la carga
-
Carga JavaScript de manera asíncrona.
Usa carga diferida para todos los componentes como archivos JS grandes, videos, iframes, widgets y también imágenes. Aprovecha el lazy-loading nativo del navegador (atributos loading e importance), o mediante una solución que use Intersection Observer. La segunda solución también puede usarse para un potente "scrollytelling" - efecto tipo parallax, o seguimiento de anuncios.
-
Retrasa el renderizado y decodificación de imágenes grandes.
Con la propiedad content-visibility: auto, podemos instruir al navegador para que omita el renderizado de los descendientes de un elemento dado si ese elemento está fuera del viewport. Asegúrate de usar la propiedad contain-intrinsic-size con un placeholder apropiadamente elegido, para evitar empeorar la métrica de Desplazamiento Acumulativo del Diseño (CLS). Usa también
<img decoding="async">. El navegador entonces decodificará la imagen fuera del hilo principal y se reducirá el tiempo de CPU necesario para la operación. -
Carga CSS crítico lo más rápido posible.
Extrae de CSS todos los estilos necesarios para renderizar el contenido visible en la página en el viewport (también conocido como CSS crítico o CSS encima del pliegue). Agrega estos estilos como inline en la etiqueta
<head>de la página. La regla de oro es no exceder un tamaño total de 14 kB. Considera la inyección condicional de CSS en la página. En algunos casos, puede ser más rentable colocar el CSS crítico en un archivo separado en la raíz del dominio. Debido al almacenamiento en caché, esta solución puede ser mejor que insertar estilos inline. -
Experimenta con la reordenación de archivos/propiedades CSS.
Al optimizar la carga, también puedes considerar dividir el CSS principal por differentes media queries. No coloques
<link rel ="stylesheet"/>antes de archivos asíncronos. Si los scripts no dependen de los estilos, considera colocar scripts bloqueantes por encima de estilos bloqueantes. Si lo hacen, divide ese JavaScript en dos y cárgalo antes y después de los archivos CSS. Almacena en caché CSS embebido usando service workers y experimenta con CSS en el cuerpo. Los estilos dinámicos pueden ser "costosos": verifica si CSS-in-JS optimiza la ejecución, si CSS no tiene dependencias de apariencia o propiedades de componentes, no compliques los componentes (styled-components). -
Transmite respuestas.
El streaming proporciona una interfaz para leer o escribir bloques asincrónicos de datos, de los cuales un subconjunto puede estar disponible en memoria en un momento dado. En lugar de servir un esquema de interfaz de usuario vacío y poblar el contenido con JavaScript, usa un service worker, almacena el esquema en caché y el contenido de la red. El HTML renderizado durante la solicitud inicial podrá entonces aprovechar al máximo el parser HTML del navegador.
-
Considera adaptar tus componentes a la conexión y memoria del dispositivo.
Usa la cabecera de client-hint Save-Data y adapta la aplicación a las limitaciones de tus usuarios (costo, rendimiento). Puedes sobrescribir las solicitudes de imágenes de alta resolución a baja resolución, eliminar fuentes web, parallax, desactivar la reproducción automática de video o incluso cambiar cómo entregas código. Usa el Network Information API para entregar variantes de componentes pesados según la conexión y el Device Memory API para adaptar los recursos según la memoria del dispositivo.
-
Mantén conexiones persistentes para acelerar la entrega.
Ahorra tiempo usando resource hints; dns-prefetch (búsqueda DNS en segundo plano), preconnect (inicia el handshake de conexión (DNS, TCP, TLS)), prefetch (solicitud de recursos), preload (precarga de recursos sin ejecutarlos) y prerender (carga de recursos previamente sin ejecutar JS y sin renderizado en la página). Al usar preload, debe definirse as, o no se cargará nada. Precargar fuentes sin el atributo crossorigin provocará una carga doble. Al usar preload hay una serie de prioridades, así que considera insertar elementos rel=”preload” en el DOM justo antes de los scripts bloqueantes externos.
-
Usa service workers para almacenar en caché y como respaldo ante fallos de red.
Si tu sitio web se ejecuta en HTTPS, almacena recursos estáticos en la cache del service worker (caché) y guarda un respaldo fuera de línea (o incluso páginas completas) y cógelas del dispositivo en lugar de la red. Almacena el entorno de la aplicación en la cache del service worker junto con algunas páginas críticas, como una página sin conexión o la página de inicio. Pero, asegúrate de que haya un encabezado CORS de respuesta correcto, no almacenes respuestas opacas y registra imágenes cross-origin en modo CORS.
-
Usa service worker en CDN/Edge (por ejemplo, para pruebas A/B).
En CDN que implementan service workers en el servidor, considera ajustar el rendimiento usando service workers directamente "en el borde". Por ejemplo, en pruebas A/B, cuando HTML necesita cambiar su contenido para diferentes usuarios, usa un service worker en la CDN para manejar la lógica service worker en CDN.
Acelera sitios que usan fuentes de Google mediante stream HTML rewriting.
-
Optimiza el rendimiento del renderizado.
Si es necesario, aísla componentes costosos usando css containment. Asegúrate de que al desplazarte por la página o al animar un elemento no haya ningún retraso y que mantengas constantemente una velocidad de 60 fotogramas por segundo. Si no es posible, intenta mantener la velocidad de los fotogramas al menos constante. Se considera que la velocidad mínima de repintado es de 15 fotogramas por segundo. Usa CSS will-change para informar al navegador sobre qué elementos cambiarán.
-
¿Está optimizada la experiencia de renderizado?
No subestimes el papel de la velocidad percibida. Si estás cargando archivos, intenta estar siempre un paso adelante del cliente, para que la experiencia sea fluida, incluso cuando muchas cosas ocurren en segundo plano. Para captar la atención del cliente, usa "skeletons" en lugar de ruedas de carga y agrega transiciones y animaciones.
-
Evita los reflows y repaints.
Los reflows suelen ser provocados por cambios en el tamaño de componentes como videos e imágenes, además de la carga diferida de fuentes web, anuncios insertados o la carga diferida del contenido real en los componentes. Establece width y height en las imágenes para que los navegadores modernos puedan reservar el espacio necesario. Usa SVG placeholders para reservar suficiente espacio, en el que aparecerán imágenes o videos. Usa lazy-loading JavaScript si no hay disponible una versión nativa para el componente. Descarga el JS lazy-loading solo si realmente lo vas a utilizar. Identifica los reflows causados por fuentes web y compara el line-height y los espacios usando font-style-matcher. Monitorea la estabilidad del diseño con Layout Instability API y la métrica Cumulative Layout Shift (CLS).
Red y HTTP/2
-
¿Tienes habilitado OCSP stapling?
OCSP stapling puede acelerar el proceso de autenticación TLS, ya que el navegador no necesita perder tiempo buscando y descargando información del certificado de tu dominio.
-
¿Has reducido el impacto de la revocación del certificado SSL?
Los certificados Extended Validation (EV) son caros y requieren mucho tiempo, ya que siempre deben ser verificados por un humano. Los certificados Domain Validation (DV) ordinarios están disponibles de forma gratuita (Let's Encrypt) y su obtención y renovación pueden automatizarse fácilmente. Además, los certificados EV no admiten OCSP stapling, por eso siempre ten un certificado DV con stapling habilitado.
-
¿Usas IPv6?
Los estudios muestran que los sitios web son hasta un 15% más rápidos gracias a NDP (Neighbor Discovery Protocol) y la optimización de rutas. Actualiza tus registros DNS para que tu sitio web sea accesible también a través de IPv6. No olvides el IPv4 existente, ya que ambas versiones no son compatibles entre sí.
-
¿Se usa TCP BBR?
BBR es un algoritmo relativamente nuevo de control de flujo del protocolo TCP. Reacciona más al verdadero congestionamiento que a la pérdida de paquetes, como lo hace TCP. Como tal, es significativamente más rápido, con mayor rendimiento y menor latencia. Habilita BBR y configura tcp_notsent_lowat en 16 kB, para que la priorización en HTTP/2 funcione de manera confiable en núcleos Linux 4.9 y más recientes.
-
Prioriza siempre HTTP/2.
HTTP/2 está muy bien soportado y ofrece un aumento de velocidad. Dependiendo de cuán grande sea tu base de usuarios móviles, es posible que necesites enviar diferentes builds (construcciones de aplicaciones) a los usuarios y podrías beneficiarte de adaptar diferentes builds para diferentes dispositivos. (HTTP/2 es a menudo más lento en redes con una tasa de pérdida de paquetes notable).
-
Implementa correctamente HTTP/2.
Debes encontrar un equilibrio entre fusionar módulos en uno solo y cargar en paralelo muchos módulos pequeños. Divide toda tu interfaz en muchos módulos pequeños; luego agrúpalos, comprímelos y haz bundles. Divídelos a nivel de paquetes o monitoreando qué bloques CSS/JS no se usan. Separa el código de terceros del tuyo propio y separa las dependencias que cambian raramente y frecuentemente. Enviar aproximadamente 6–10 paquetes de elementos frontend parece un buen compromiso (y no es malo para navegadores más antiguos). Experimenta y mide para encontrar el equilibrio adecuado. Intenta enviar el mayor número de elementos posible a través de una conexión HTTP/2.
-
¿Tus servidores y CDN admiten HTTP/2?
Diferentes servidores y CDN admiten HTTP/2 de manera diferente. Usando herramientas que comparan CDN (por ejemplo, CDN Comparison), puedes verificar tus opciones o buscar rápidamente el nivel de soporte de diferentes características. Habilita BBR, establece tcp_notsent_lowat en 16 kB para la priorización en HTTP/2.
-
¿Se usa la compresión HPACK?
Si usas HTTP/2, verifica que tus servidores implementen compresión HPACK para los encabezados de respuesta HTTP, para reducir la sobrecarga innecesaria. Los servidores HTTP/2 son relativamente nuevos y pueden no admitir completamente la especificación, como HPACK. H2spec es una excelente herramienta (aunque técnicamente demasiado detallada) para verificar esto.
-
Prepárate para HTTP/3.
En HTTP/2, una conexión comparte múltiples solicitudes. En HTTP/3, también las solicitudes comparten una conexión, pero se transmiten de forma independiente, por lo que un paquete descartado ya no afecta a todas las solicitudes, solo a un stream. Con QUIC en HTTP/3, TCP y TLS se combinan y ejecutan en un único "viaje de ida y vuelta". A partir de la segunda conexión, ya podemos enviar y recibir datos de capa de aplicación en el primer "viaje de ida y vuelta" (0-RTT). Todavía importa el empaquetado de elementos frontend, por lo que en lugar de enviar JS monolítico, envía varios archivos JS en paralelo, como en HTTP/2. Espera un impacto de HTTP/3 en los tiempos de carga en dispositivos móviles.
-
¿Tus servidores y CDN admiten HTTP/3?
QUIC y HTTP/3 son mejores y más robustos: con "handshakes" más rápidos, mejor cifrado, streams independientes más confiables, más cifrados y con 0-RTT si el cliente ya ha tenido una conexión al servidor antes. Sin embargo, es bastante exigente en cuanto a CPU (2–3 veces el uso de CPU para el mismo ancho de banda). Verifica si tus servidores o CDN admiten el protocolo HTTP sobre QUIC (también conocido como HTTP/3) y, si puedes, habilítalo.
-
Verifica que la seguridad en tu servidor sea a prueba de balas.
Asegúrate de que las cabeceras de seguridad estén configuradas correctamente, elimina las vulnerabilidades conocidas y verifica la configuración HTTPS. Asegúrate de que todos los plugins externos y scripts de seguimiento estén cargados a través de HTTPS, que el scripting entre sitios no sea posible y que las cabeceras HTTP Strict Transport Security y Content Security Policy estén configuradas correctamente.
Pruebas y monitoreo
-
Monitorea las advertencias de contenido mixto (mixed-content).
Si has migrado recientemente de HTTP a HTTPS, no olvides monitorear las advertencias activas y pasivas de contenido mixto usando herramientas como Report-URI.io. También puedes usar Mixed Content Scan para escanear contenido mixto en tu sitio web con soporte HTTPS.
-
¿Has optimizado el flujo de trabajo de auditoría y depuración?
Invierte tiempo en estudiar técnicas de depuración y auditoría en tu depurador, WebPageTest, Lighthouse y amplía tu editor de texto. Por ejemplo, puedes ejecutar WebPageTest desde una hoja de cálculo de Google e integrar las puntuaciones de accesibilidad, rendimiento y SEO en tu configuración de Travis usando Lighthouse CI o directamente en Webpack. Para verificaciones rápidas, usa CSS Perf Diagnostic.
-
¿Has probado en navegadores proxy y navegadores más antiguos?
Probar en Chrome y Firefox no es suficiente. Mira cómo funciona tu sitio web en navegadores proxy y navegadores más antiguos (incluidos UC Browser y Opera Mini). Mide la velocidad promedio de Internet entre tu base de usuarios, para evitar grandes sorpresas. Prueba con limitación de red y emula dispositivos con alta DPI. BrowserStack es fantástico, pero también prueba en dispositivos reales.
-
¿Has probado la velocidad de tus páginas 404?
Cada vez que un cliente solicita un elemento en el sitio web que no existe, recibe una respuesta 404 — y esta respuesta suele ser enorme. No olvides investigar y optimizar la estrategia de almacenamiento en caché también para tus páginas 404. Asegúrate de que el navegador muestre HTML solo si espera una respuesta HTML, y para todas las demás respuestas devuelva una respuesta de error.
-
¿Has probado el impacto de tus consentimientos de GDPR y barras de cookies?
Normalmente, las solicitudes de consentimiento para cookies no deberían afectar el CLS, pero a veces puede suceder, por lo que considera usar recursos gratuitos y de código abierto como Osano o cookie-consent-box. El consentimiento probablemente cambiará el impacto de los scripts en el rendimiento general, por lo que establece y estudia varios perfiles de prueba de rendimiento web para diferentes tipos de consentimiento.
-
¿Has probado el impacto en la accesibilidad?
Las páginas grandes y la manipulación del DOM con JavaScript causarán retrasos en las notificaciones de los lectores de pantalla. Un rápido Time to Interactive significa cuánto tiempo pasa antes de que el lector de pantalla pueda anunciar la navegación a la página dada y el usuario del lector de pantalla pueda realmente presionar el teclado para interactuar.
-
¿Está configurado el monitoreo continuo?
Las buenas métricas de velocidad surgen de combinar herramientas de monitoreo pasivo y activo. Una instancia privada de WebPagetest y el uso de Lighthouse siempre es ventajoso para pruebas rápidas, pero también configura el monitoreo continuo usando herramientas RUM, como SpeedTracker, SpeedCurve y otras. Establece tus propias marcas de tiempo de usuario (user-timing marks) para medir y monitorear métricas específicas de tu sitio web.
Victorias rápidas
La Lista de verificación de velocidad web es bastante completa, y completar todas las optimizaciones puede llevar tiempo. Entonces, si solo tuvieras 1 hora para obtener mejoras significativas, ¿qué harías? Resumamos todo en 18 frutos fáciles de alcanzar. Por supuesto, antes de comenzar y una vez que termines, mide los resultados, incluidas las métricas Largest Contentful Paint y Time To Interactive en 3G y también en conexión por cable.
- Mide la velocidad entre usuarios reales y establece objetivos adecuados. Esfuérzate por ser al menos un 20% más rápido que tu competidor más veloz. Mantén el Largest Contentful Paint por debajo de 2,5 s, First Input Delay debajo de 100 ms, Time to Interactive por debajo de 5 segundos en 3G lento, para visitas repetidas por debajo de 2 s. Optimiza al menos para First Contentful Paint y Time To Interactive.
- Optimiza imágenes usando Squoosh, mozjpeg, guetzli, pingo y SVGOMG y sirve AVIF/WebP con una CDN de imágenes.
- Prepara CSS crítico para tus plantillas principales e insértalos inline en el
<head>de cada una de ellas. Para CSS y JS, ten un presupuesto para el tamaño de los archivos críticos de máx. 170 kB tras gzip (0,7 MB descomprimido). - Recorta, optimiza, retrasa y carga de manera diferida los scripts. Invierte en la configuración de tu bundler para eliminar redundancias y busca alternativas menos voluminosas.
- Aloja siempre los archivos estáticos del frontend en tu propio dominio. Prefiere también alojar componentes de terceros en tu propio dominio. Limita su impacto. Usa fachadas y placeholders, carga widgets tras la interacción y cuida del parpadeo de la versión original.
- Al elegir un framework, sé exigente. En aplicaciones de una sola página (SPA), identifica páginas críticas y renderízalas estáticamente, o al menos prerenderízalas. Usa hidratación progresiva a nivel de componentes e importa módulos al interactuar.
- Solo el renderizado del lado del cliente no es una buena opción para el rendimiento. Prerenderiza si tus páginas no cambian mucho, y retrasa el inicio de los frameworks. Usa renderizado en streaming del lado del servidor (SSR).
- Proporciona código legacy solo a navegadores antiguos usando el patrón de diseño module/nomodule.
- Experimenta con la reordenación de reglas CSS y prueba CSS servido directamente en HTML.
- Añade sugerencias de recursos (resource hints) para acelerar la entrega usando dns-lookup, preconnect, prefetch, preload, prerender.
- Subsetea las fuentes web y cárgalas de manera asíncrona, utiliza font-display en CSS para un rápido primer renderizado.
- Verifica que las cachés HTTP y las cabeceras de seguridad estén configuradas correctamente.
- Habilita la compresión Brotli en el servidor. (Si no es posible, asegúrate de habilitar la compresión Gzip).
- Habilita el control de flujo TCP con BBR, si tu servidor se ejecuta en un kernel de Linux versión 4.9+.
- Si es posible, habilita OCSP stapling e IPv6. Siempre sirve un certificado DV con OCSP.
- Habilita compresión HPACK para HTTP/2 y migra a HTTP/3, si está disponible.
- Cachea elementos como fuentes, estilos, JavaScript e imágenes en la caché del Service Worker.
- Explora opciones para evitar la rehidratación, usa hidratación progresiva y renderizado en streaming del lado del servidor para tu aplicación de una sola página (SPA).
Agradecimientos especiales por la revisión del artículo original en Smashing Magazine a Guy Podjarny, Yoav Weiss, Addy Osmani, Artem Denysov, Denys Mishunov, Ilya Pukhalski, Jeremy Wagner, Colin Bendell, Mark Zeman, Patrick Meenan, Leonardo Losoviz, Andy Davies, Rachel Andrew, Anselm Hannemann, Barry Pollard, Patrick Hamann, Gideon Pyzer, Andy Davies, Maria Prosvernina, Tim Kadlec, Rey Bango, Matthias Ott, Peter Bowyer, Phil Walton, Mariana Peralta, Pepijn Senders, Mark Nottingham, Jean Pierre Vincent, Philipp Tellis, Ryan Townsend, Ingrid Bergman, Mohamed Hussain S. H., Jacob Groß, Tim Swalling, Bob Visser, Kev Adamson, Adir Amsalem, Aleksey Kulikov y Rodney Rehm.
Traducción al español: Tomás Hejč, Martin Brychta, Zuzana Fatrdla, Martin Michálek. (Equipo PageSpeed.ONE)
Mantén el control sobre la velocidad de tu sitio web.
Suscríbete a nuestro boletín. Cada mes seleccionamos novedades sobre la velocidad web para propietarios, marketers y desarrolladores.
Etiquetas:Web Performance