La primera versión de esta publicación proviene de una conferencia en QCon sobre cómo optimizar el desempeño de la carga de páginas en la Web.
¿Por qué es tan importante optimizar nuestros Sitios Web? Simplemente porque a ningún usuario le gusta perder el tiempo esperando que se carguen las páginas. Es extremadamente irritante. Y esto tiene graves consecuencias, como muestran estos estudios:
Pero hablar de optimizaciones del navegador en un evento como QCon puede parecer básico. Tantos arquitectos, discusiones de alto nivel sobre nuevas plataformas como Node.JS y procesamiento asincrónico, varias conferencias sobre computación en la nube (cloud computing), todos usan memcache y muchas otras técnicas avanzadas.
Entonces, para contextualizar aún más la discusión, analicé los datos de los Sitios de todos los participantes del evento. Basándome en los correos electrónicos de los inscritos (descartando correos web como GMail, Hotmail, etc.), separé más de 100 dominios para pruebas, incluyendo grandes portales brasileños, empresas de tecnología, sitios web gubernamentales y otros. Envié todo al WebPageTest.org y recompilé los resultados.
El número más importante, el tiempo total de carga, ya da una idea de la situación. Los sitios analizados tardan, en promedio, 9 segundos para cargarse, algunos de los cuales tardaron más de 40 segundos. Y la gran verdad es que el desempeño final para el usuario depende mucho más del client-side que del server-side. De todos los sitios analizados, la inmensa mayoría, el 75%, tuvo un tiempo de procesamiento de menos de 400 ms en el servidor.
Hay mucho margen de mejora en la mayoría de los Sitios. Y la conferencia cubre varios temas de optimización.
Buena práctica en cualquier aplicación distribuida es reducir el payload, es decir, el volumen de datos transferidos, es un principio básico. Y hay varias formas de hacerlo.
Al analizar las páginas de los participantes del evento, el tamaño medio fue de 860 kb. Además, el 35% de los Sitios tienen un tamaño superior a 1 MB, y el peor de los casos alcanzaba los increíbles 8 MB.
Hace mucho tiempo digo que habilitar GZIP en el servidor es el primer paso. No tarda más de 30 segundos y es compatible con todos los navegadores y servidores durante los últimos 15 años. Con él, todo el contenido textual (HTML, CSS, JS, etc.) se comprime antes de ser enviado al cliente, acortando más del 50% del tráfico total.
Sin embargo, en el análisis de los Sitios, encontré que el 43% de todos los requests textuales no estaban gzipados. Más: solo el 14% de los Sitios tenía gzip en todos los requests.
Un código JS bien hecho está bien documentado, todo identificado y tiene nombres de variables legibles. Pero nada de eso cuenta para ejecutar el script, y el tráfico de ese montón de bytes es un desperdicio. En cuestión de minutos, es posible integrar una herramienta de minificación de JavaScript, como YUI Compressor, Google Closure Compiler o UglifyJS.
Muchos Sitios generalmente incluyen algunos scripts ya minificados como jQuery (con su archivo jquery-min). A pesar de esto, de los Sitios analizados, solo el 13% minificaba todos los JavaScripts.
Minificar los archivos CSS es igualmente importante. Para eso, podemos usar el YUI Compressor e incluso el LESS compiler.
El código HTML también se puede comprimir, eliminando espacios, comentarios e incluso ciertas comillas y cierra tags innecesarias. Google, por ejemplo, no cierra </html>
o </body>
en su home, ya que esto no perjudica a ningún navegador y ahorra algunos bytes más.
El excelente HTML Compressor permite varias optimizaciones y es muy configurable. Comprimir HTML no suele ser sencillo porque, en general, tratamos con páginas dinámicas.
Principio básico de optimizaciones, nunca dejar de reducir imágenes configurando el width
y height
en HTML o CSS. Siempre redimensione el archivo original y haga referencia al tamaño directo.
Dentro de un archivo PNG o JPG, se guardan muchos datos. Además de la información de la imagen en sí, hay metadatos como EXIF y, a veces, incluso una miniatura de la imagen en sí. Nada de esto es necesario para renderizar la imagen en la pantalla y se puede eliminar. Este tipo de optimización, llamada lossless, sin pérdida de calidad visual, es lo mínimo que debe hacer cualquier aplicación. Con el Smush.it, por ejemplo, simplemente envíe las imágenes y recíbelas de vuelta optimizarlas. Otras herramientas incluyen el ImageOptim además de varias opciones de línea de comando para la automatización (pngquant, optipng, pngcrush, pngout, advpng).
La optimización de imágenes es esencial porque a menudo son la parte más pesada de las páginas Web. En el análisis de los Sitios de los conferencistas, en promedio, 47% de los bytes de la página eran imágenes.
A pesar de esto, solo el 15% de los Sitios optimizan todas las imágenes. Para 1/4 de los Sitios, la optimización de las imágenes ahorraría más del 40% de los bytes totales.
Pero también es posible aplicar transformaciones lossy, es decir, disminuir la calidad de las imágenes para mejorar el desempeño. Muchos diseñadores ni siquiera consideran esta posibilidad, pero el hecho es que mucho en el mundo es lossy. Un MP3, por ejemplo, disminuye la calidad del audio original para promover la movilidad. Disminuir la calidad de una foto JPEG con poco impacto visual notable puede generar enormes ganancias. El nuevo servicio JPEGMini, por ejemplo, tiene un algoritmo avanzado que disminuye la calidad de JPEG basándose en un modelo matemático que simula las características de la percepción humana. El resultado son imágenes que tienen menos de la mitad del tamaño y son visualmente idénticas.
Los formatos de imagen que se pueden utilizar en la Web son PNG, JPEG y GIF. Pero, ¿cuál usar y cómo elegir el formato correcto? Hay varios factores. PNG y GIF mantienen la fidelidad de la imagen; JPEG es un formato lossy cuya compresión siempre causa pérdida de calidad (de hecho, es por eso que nunca debes editar archivos JPEG directamente; cada vez que guardas el archivo, pierdes calidad). Como resultado, un PNG suele ser más interesante para gráficos cuando las fotos son más pequeñas en JPEG.
Otro punto es que los PNG admiten la transparencia del canal alfa, mientras que los GIF solo tienen transparencia total y JPEG no admite la transparencia. En general, los PNG de hoy son superiores a los GIF y la única razón para usar estos últimos es cuando hay animaciones.
Pero incluso cuando usa PNG, puede elegir entre dos formatos diferentes: PNG8 y PNG24. El PNG clásico es un PNG de 24 bits que admite millones de colores y se exporta de forma predeterminada por todas las herramientas gráficas. Pero PNG8 reduce la paleta a 8 bits, 256 colores como máximo, al igual que los viejos GIF. La ventaja de PNG8 es que tiene un tamaño mucho menor y es muy útil para imágenes con pocos colores (logotipos, gráficos simples, etc.).
Un último paso para reducir el tráfico es minimizar los encabezados involucrados en la solicitud y la respuesta. De estos, las cookies son a menudo el peor villano, ya que se envían en cada solicitud entre el cliente y el servidor. Incluso hay una recomendación de servir contenido estático de dominios sin cookies.
Otro principio básico de cualquier sistema distribuido, minimizar el número de invocaciones remotas es fundamental para un buen desempeño. En la Web, esto significa reducir los requests realizados en la página para recursos externos: archivos JS, CSS, imágenes, Flash, videos, etc.
En el estudio de los Sitios de los participantes de QCon, el promedio de requests es de 65 por página, con un 17% que tiene más de 100 requests.
El análisis mostró que, en promedio, los Sitios llaman a 10 archivos JavaScript externos. El peor de los casos fue un Sitio que llamó a increíbles 54 archivos JS. La solución es sencilla: juntar varios archivos y reducir el total. Lo ideal es que la aplicación lo haga dinámicamente o en build time, de modo que no sea necesario hacerlo manualmente. No hay un número ideal de archivos JS, pero recomiendo, como máximo, entre 3 y 5 archivos.
El mismo principio se aplica a los archivos CSS. En ese caso, recomiendo 1 o 2 archivos externos. En el análisis de los Sitios, el promedio fue de 5 archivos por página, y en el peor de los casos llegó a 24 archivos CSS externos.
Aplicar la misma idea de juntar archivos a imágenes no es tan sencillo. Los sprites son imágenes que combinan varias otras en una, como la que se usa en Google:
El problema es crear estas imágenes, que es difícil de automatizar y gestionar el CSS necesario para colocar cada pieza en el lugar correcto. Hay ideas para la automatización como Sprite.me, SpriteMapper, SpriteCow y SmartSprites.
Al crear sprites, se deben considerar muchos puntos: es difícil lidiar con imágenes que necesitan repetición. Es necesario pensar en el espacio entre imágenes para facilitar el posicionamiento en el CSS, sin dejar el sprite con un área muy grande, lo que provocaría un gran uso de memoria en el navegador. Es necesario pensar en la similitud de las imágenes para que, al unirlas, no tengamos una paleta de colores más grande y poca compresión. Tenemos que decidir el formato del sprite (¿PNG? ¿JPEG?) Y cómo unificar las mismas características de calidad y compresión de diferentes imágenes.
Los Sprites son complicados de hacer, pero esenciales para una optimización seria. Al analizar los Sitios de los participantes de QCon, más de la mitad de referencia 36 imágenes o más. En el peor de los casos, se incluyeron 144 imágenes en una sola página.
Esta es una característica peligrosa pero extremadamente útil. Así como podemos embutir contenido CSS y JS en el medio del HTML cuando sea conveniente, con las data URIs, podemos embutir imágenes y otros elementos binarios. No es un recurso para abusar, ya que aumenta el tamaño del HTML y no permite que la imagen sea almacenada en caché y referenciada en diferentes lugares. Es posible utilizar data URI en archivos CSS almacenables en caché, que es una práctica más recomendada.
La idea es transformar los datos binarios de una imagen en base64 y colocarlos directamente en el src de una imagen. Un problema es que IE solo es compatible a partir de la versión 8, aunque todos los demás navegadores lo han soportado durante mucho tiempo. Esto no le impide ofrecer diferentes versiones del Sitio para navegadores más antiguos, por ejemplo. Google Images es un ejemplo emblemático de uso de data URI.
La estrategia aquí es permitir que los recursos estáticos sean almacenados en caché por el navegador, evitando nuevos requests cuando el usuario vuelva a visitar la página. En unos segundos es posible configurar el servidor para que atienda requests con valores adecuados de Expires
, Last-Modified
, Cache-Control
y ETag
.
En el estudio de los Sitios, descubrí que al acceder dos veces a la misma página, el segundo acceso dispara, en promedio, 46 nuevos requests. Y también el 87% de los sitios dispararon más de 10 requests en este segundo acceso, una fuerte indicación de que se hace poco uso de la función de caché del navegador. Un valor razonable sería mantener ese número en menos de 5 requests y, si es posible, solo 1 o 2.
Controvertido, este tema propone que el diseño se haga teniendo en cuenta el desempeño. Quizás muchos diseñadores y diseñadoras no estén de acuerdo, pero los números muestran que la velocidad es más importante para el usuario que los diseños detallados y cargados.
Esta práctica incluye reducir la dependencia del layout para imágenes externas, evitar el uso de fuentes externas, no usar Flash para diseño, entre otros.
La percepción humana es mucho menos racional de lo que pensamos. Y, en la Web, esto refleja directamente cómo los usuarios perciben la velocidad del Sitio (y credibilidad, atractivo, etc.). Hay estudios que muestran que la percepción de los usuarios sobre el tiempo de carga es, en promedio, un 15% peor que la real. Y, cuando se le pregunta posteriormente sobre el desempeño de un Sitio, la memoria suele ser un 35% peor que la velocidad real (fuente).
En la web, la cantidad de segundos que tarda la página en cargarse y la nota YSlow son métricas importantes, pero no es solo eso. Performance Web se trata de usabilidad y UX, y es el usuario final quien dice lo rápido que es o no un Sitio.
Existen varias técnicas de optimización que no afectan el tiempo de carga de la página y pueden no mejorar su calificación de YSlow. Son técnicas para hacer más favorable la percepción del usuario a su Sitio, dando la sensación de velocidad aunque el reloj indique lo contrario.
Fácil de implementar, esta práctica tiene un gran impacto visual para el usuario. Cuando no especificamos el tamaño de la imagen, el navegador no reserva un espacio en la página para ello. El efecto es que cuando llega la imagen, se coloca en su lugar empujando el resto del contenido. Esto da la sensación de que los elementos de la página se mueven y que la página aún no se ha cargado. Es una práctica de usabilidad terrible y da la sensación de más lentitud.
Simplemente especificar el tamaño correcto de la imagen en el ancho y alto del HTML o CSS hace que el navegador reserve espacio para la imagen incluso antes de que se complete la descarga. Cuando llega, el navegador no necesita hacer espacio y empujar el resto de elementos, dando la sensación de que la página se carga más rápido. Además, al evitar el reposicionamiento de elementos, evita reflowss y repaints desnecesarios.
El código JavaScript, interno o externo, bloquea la representación de todo lo que se encuentra debajo. En algunos navegadores, incluso bloquea la descarga de componentes siguientes. Para evitar este bloqueo, coloque JavaScript lo más abajo que pueda; si es posible, justo antes de cerrar el body.
El efecto más común de JavaScript mal posicionado es que la pantalla se queda en blanco durante mucho tiempo, lo que retrasa el inicio de la renderización. El sentido común tiene JavaScripts colocados en el head, lo que hace que se bloquee la renderización de toda la pantalla. Al analizar los Sitios de los conferencistas, la espera promedio para que comience la renderización fue de 4.3 s. El peor de los casos dejó el navegador totalmente en blanco durante 25 segundos. El Sitio web de Alura, por ejemplo, comienza la renderización en aproximadamente 0,7 segundos.
CSS también bloquea la renderización de la pantalla, pero, en este caso, es mejor la mayor parte del tiempo. Dejar el CSS tendría el efecto conocido como FOUC – Flash of Unstyled Content. La página se renderiza sin estilo y, cuando se acaba de descargar el CSS, se rediseña con estilo.
Aunque esto hace que la página comience a mostrarse ante el usuario, en la mayoría de los Sitios, mostrar una página sin estilos no tiene ningún valor para el usuario. El diseño es sin estructura, sin organización, y el efecto es que la página está tardando más en cargarse. Por eso, coloque el CSS al tope del documento, preferiblemente en el head.
Una de las técnicas avanzadas más discutidas últimamente, y la más efectiva, es el uso de la carga asíncrona de los componentes de la página. Esto evita bloquear la renderización y hace que la página sea más responsiva.
Como dice el dicho, la primera impresión es la que cuenta. Esto significa optimizar al máximo la primera visita del usuario, aquella en la que la caché del navegador estará vacía, aquella en la que aún no conoce su Sitio y aquella en la que trae todas sus expectativas. Es necesario comprender cómo ocurre la interacción del usuario y priorizar los componentes y el orden de renderización de la página para ese primer contacto. Algunos hablan de una nueva métrica, el Above the Fold Time – AFT - que mide el tiempo de carga desde el inicio de la página, "arriba de la página", esa parte que el usuario ve sin desplazarse. El scroll infinito de Twitter es un ejemplo de esto; los datos inferiores solo se cargan cuando el usuario se desplaza allí. O la página del producto de Amazon que le permite cargar algunos componentes al final de la página solo cuando el usuario llega allí.
Incluso sin utilizar técnicas avanzadas como el desplazamiento infinito, priorizar AFT es pensar en el orden de los elementos en HTML para que las cosas que se mostrarán antes se carguen primero. Posponer ese widget de Facebook en la parte inferior de la página para que se cargue solo después del onload, por ejemplo. Proporciona un menú de opciones que no depende de JavaScript para funcionar, ya que se ejecutará en último lugar. Al final, se trata de centrarse en la primera experiencia de usuario y posponer todo lo que no sea necesario para ello.
Un área que merece una publicación para sí es cómo el diseño de la página puede afectar la percepción de velocidad del usuario. Google Reader solía usar un fondo azul claro en su barra lateral y decidió intentar cambiar a blanco. Cuando se les preguntó, la mayoría de los usuarios dijeron que el "nuevo sitio" era más rápido que el anterior (fuente).
La Psicología del Desempeño involucra muchos temas de diseño, UX y usabilidad. Un diseño más ligero, una arquitectura de información más simple, una call-to-action más directa influencian directamente sobre cómo los usuarios perciben el desempeño.
El secreto de un Sitio web con un desempeño constante y perdurable es automatizar el proceso. Haz un script que minifique JS y CSS, automatice la optimización de imágenes, etc. Cualquier proceso repetitivo debe ser automatizado, de lo contrario pronto el equipo lo dejará de lado.
Supervise tus páginas constantemente con herramientas de diagnóstico. Hay varias disponibles:
En algunos casos, al visitar una página, es casi seguro que sepa cuál será la siguiente página visitada por el usuario. Piense en la página de inicio de Google que seguramente será seguida por una visita a la página de resultados de búsqueda. O incluso en un flujo de cierre de compras desde una tienda virtual en varios pasos.
En estas situaciones, puede ser interesante que la primera página precargue elementos que se utilizarán en la página siguiente. CSS, JavaScript e imágenes se pueden precargar mediante código, anticipando la descarga de componentes que probablemente se utilizarán más adelante. Obviamente, esta práctica sólo debe usarse si has configurado los encabezados de la caché correctamente, de lo contrario, los componentes se descargarán dos veces.
Esta práctica tiene una gran ganancia de velocidad al visitar la segunda página. Sin embargo, se debe tener cuidado de que el desempeño del primero no se vea afectado. Lo ideal es hacer estas precargas solo cuando la página de inicio termine de cargar todos sus componentes, posiblemente después del onload de la misma.
En algunos casos raros, el desempeño puede verse afectado en gran medida por prácticas deficientes de codificación HTML, CSS o JavaScript. Sin embargo, tenga en cuenta que la mayoría de las técnicas más eficaces tienden a estar poco influenciadas por las optimizaciones de microcódigo; el problema suele ser más estructural.
Sin embargo, cuando la aplicación está cargada, repleta de ricos recursos, el código se puede optimizar. Hay varios selectores CSS que hacen que la renderización sea mucho más lenta. La gran cantidad de elementos en el DOM también reduce el desempeño. Usar demasiados iframes es casi un crimen. Y también están las prácticas de optimización de código y lógica JavaScript, como dividir tareas largas en partes más pequeñas con WebWorkers o setTimeout, evitando el bloqueo de pantalla.
Muchos scripts esperan el evento onload para que siga su ejecución. Además, suele ser la métrica que se utiliza para medir el desempeño en herramientas como Analytics y Webmasters Tools. Desde 2010, Google ha utilizado la velocidad del Sitio como una de las variables del ranking de las búsquedas, y esto tiene que ver con el onload. Después del disparo del onload, el indicador de carga del navegador deja de girar, dando la impresión de que la carga está completa.
Hay varias razones para optimizar el tiempo de onload, muy explicados por Steve Souders en sus libros. Abusar de la carga asíncrona ayuda a implementar esta práctica.
No te limites a los números exactos que le da su herramienta de diagnóstico. Rompa algunas reglas cuando sean mejores para el usuario. La técnica de precargar componentes en la página siguiente empeorará su calificación en YSlow, a medida que aumenta el número de requests, aumenta el tamaño total; pero es una técnica que sabemos que mejora el desempeño del usuario.
Varias de las otras reglas se pueden romper en casos específicos. Algunos dicen que las páginas de inicio de portales deben incorporar CSS y JS directamente en HTML para ahorrar requests. Algunas personas argumentan que JavaScript no debería estar al final de la página, sino justo después del fold, ya que no hay mucho problema para bloquear la renderización de la parte no visible de la página. Hay situaciones en las que desea redimensionar imágenes en HTML, como al hacer un diseño responsivo.
No se limite a los números, concéntrese en la experiencia del usuario.
Alura ofrece cursos y formaciones completas para que aprendas nuevas tecnologías del mundo de negocios. A través de nuestra comunidad activa, clases de video de alta calidad y ejercicios prácticos, ¡Estarás preparado en poco tiempo!
Cursos de Programación, Front End, Data Science, Innovación y Gestión.
Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana
Paga en moneda local en los siguientes países
Cursos de Programación, Front End, Data Science, Innovación y Gestión.
Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana
Paga en moneda local en los siguientes países
Puedes realizar el pago de tus planes en moneda local en los siguientes países:
País | |||||||
---|---|---|---|---|---|---|---|
Plan Semestral |
483.89
BOB |
68076.59
CLP |
304837.12
COP |
65.90
USD |
264.78
PEN |
1428.79
MXN |
2977.87
UYU |
Plan Anual |
733.54
BOB |
103199.56
CLP |
462112.72
COP |
99.90
USD |
401.39
PEN |
2165.95
MXN |
4514.26
UYU |
Acceso a todos
los cursos
Estudia las 24 horas,
dónde y cuándo quieras
Nuevos cursos
cada semana