Cuando las Optimizaciones Salen Mal

Spanish audio is available in the player settings
Rate this content
Bookmark

¿Alguna vez has cargado una fuente desde el CDN de Google Fonts? ¿O has agregado el atributo loading=lazy a una imagen? Estas optimizaciones se recomiendan en todo el web, pero a veces hacen que tu aplicación no sea más rápida, sino más lenta.


En esta charla, Ivan mostrará cuándo algunas optimizaciones comunes de rendimiento salen mal, y qué debemos hacer para evitarlo.

26 min
01 Jun, 2023

Video Summary and Transcription

La charla discute casos en los que las optimizaciones comunes pueden hacer que la aplicación sea más lenta en lugar de más rápida, destacando el impacto de la implementación de un CDN en el rendimiento. El retraso en el proceso de conexión del CDN provocó que la primera pintura de contenido se retrasara. La división de código, aunque reduce el tamaño del paquete, resultó en un renderizado y rendimiento retrasados. La carga perezosa de imágenes puede causar problemas de rendimiento y la optimización de imágenes debe ser gestionada cuidadosamente. Los encabezados de enlace, pre-conexión y pre-carga pueden ayudar con las conexiones y las cascadas de carga, pero solo si los archivos se cargan más tarde.

Available in English

1. Optimizaciones que salen mal: El dilema de la CDN

Short description:

La charla discute casos en los que las optimizaciones comunes pueden hacer que la aplicación sea más lenta en lugar de más rápida. El orador comparte su experiencia con la implementación de una CDN para mejorar el rendimiento de una aplicación web. Sin embargo, las pruebas de rendimiento revelaron que el sitio se volvió más lento después de agregar la CDN. El orador explica la importancia de la puntuación de Lighthouse y cómo se calcula en base a diferentes métricas. Destaca que si bien la mayoría de las métricas se mantuvieron iguales, la métrica de First Contentful Paint empeoró después de agregar la CDN. El orador enfatiza la necesidad de analizar el renderizado fotograma a fotograma y la cascada de red para comprender el impacto de las optimizaciones. En este caso, el orador observó que las respuestas tardaban menos tiempo con la CDN, pero la métrica de First Contentful Paint se vio afectada.

Entonces, sí, el tema de mi charla es cuando las optimizaciones salen mal. Se trata de casos en los que se logra alguna optimización común, pero en cambio, hace que la aplicación sea más lenta en lugar de más rápida.

Primero, hablemos de las CDNs. ¿Quién aquí utiliza una CDN en producción? Hm, bastante gente. Genial. Una vez, hace un tiempo, yo era un desarrollador en una gran y compleja aplicación web, y la pestaña estaba lenta. Las aplicaciones lentas no son agradables, así que tuvimos un proyecto para hacer que la aplicación fuera más rápida, y como parte de ese proyecto, decidimos implementar una CDN.

Ahora, una CDN es un servicio que acerca tus archivos al usuario, ¿verdad? Si tu servidor está en Estados Unidos y el usuario está en India, con una CDN, la solicitud del paquete no necesita ir hasta Estados Unidos. Puede ir directamente al servidor de la CDN cerca del usuario en India. Entonces, nuestro servidor estaba en Estados Unidos y nuestros usuarios estaban en todo el mundo. Así que decidimos probar esta optimización. Configuramos los buckets para cargar los resultados generados, configuramos la CDN delante de eso y apuntamos todas las URL de la aplicación a ese servidor de la CDN. Básicamente, nuestro índice.html, en lugar de verse así, comenzó a verse así, con el origen de la CDN delante de todas las URL.

Hasta aquí todo bien, ¿verdad? Pero cuando ejecutamos pruebas de performance, descubrimos que de repente, el sitio no se volvió más rápido, sino más lento. ¿Alguien, por cierto, tiene alguna idea de por qué? Basado en las optimizaciones, basado en el cambio que hicimos, ¿alguien tiene alguna idea de por qué esto sucede? Ninguna mano. Bien. Bueno para mí. Así que intentemos investigar esto, como si estuviera investigándolo hoy con el conocimiento y los métodos que tengo ahora.

Lo importante de saber sobre la puntuación de Lighthouse es que no es solo una puntuación de performance abstracta, ¿verdad? Se calcula en base a estas cinco métricas. Si una métrica empeora, la puntuación total empeora. Si una métrica mejora, la puntuación total mejora. Incluso hay una calculadora para esto. Ahora, la mayoría de las métricas en estas dos pruebas, antes de agregar una CDN y después de agregar una CDN, se mantuvieron más o menos iguales. Incluso el Contentful Paint de Lars mejoró, lo cual es bueno, pero una métrica, First Contentful Paint, empeoró significativamente. Entonces, First Contentful Paint es una métrica que mide qué tan rápido se renderiza el primer contenido. Es el tiempo desde el momento en que el sitio comenzó a cargarse hasta el momento en que se renderizó su primer contenido, y empeoró.

Ahora, cada vez que tengo un sitio que tiene mejores velocidades de renderizado, como First Contentful Paint o Contentful Paint de Lars, me gusta ver el renderizado fotograma a fotograma de ese sitio, la cascada de red de ese sitio, y luego compararlos para tratar de entender qué diablos ha sucedido. Entonces, en este caso, si comparo ambas versiones de este sitio, una sin CDN y otra con CDN, notaré dos cosas importantes. La primera es que las respuestas ahora realmente tardan menos tiempo, como se pretendía. Con la CDN, estas pruebas se realizaron desde Canadá, por ejemplo, utilizando webpagetest.org, y con la CDN, este viaje de ida y vuelta fue más corto, por lo que el archivo tardó menos tiempo en descargarse que sin la CDN.

2. CDN Connection Delay and First Contentful Paint

Short description:

A pesar de que los archivos tardaron más en descargarse, la primera pintura ocurrió más tarde con la CDN. El retraso se debió al proceso de conexión, que consiste en la resolución DNS, la conexión TCP y el handshake TLS. Al agregar una CDN en un dominio separado, los archivos CSS se retrasaron, lo que también retrasó la primera pintura de contenido. Este problema no se entendió inicialmente, lo que llevó al abandono de la optimización de la CDN. Sin embargo, el orador ahora sabe cómo evitar este problema.

En segundo lugar, a pesar de que nuestros archivos tardaron más en descargarse, la primera pintura ocurrió más tarde. Puedes ver que, sin la CDN, la primera pintura ocurrió alrededor de los 2.0 segundos. Y cuando agregamos la CDN, la primera pintura comenzó a ocurrir a los tres segundos. Y si trato de entender por qué sucede, si observo la parte de la cascada que precede a la primera pintura, la primera pintura y trato de comparar qué cambió, notaré esto.

¿Alguien sabe qué significa eso? Oh, no puedo escuchar desde aquí, resulta. Pero, está bien. Algunas personas están levantando la mano. Oh, bien. Alguien sabe. Genial. Entonces, esta parte de la cascada, esta parte de la cascada es lo que nos derrotó en ese momento cuando estábamos tratando de configurar una CDN. Y ahora que trabajo con clientes, ahora que soy un consultor independiente, veo que también está afectando a mis clientes.

El problema es que cada vez que intentamos cargar algo desde un nuevo dominio, el navegador tiene que establecer una conexión con ese dominio primero. Y eso es sorprendentemente lento. Entonces, el proceso de conexión consta de tres pasos. El primer paso es la resolución DNS. El navegador obtiene el nombre de dominio al que has hecho referencia en tu HTML o algo y busca su dirección IP. Idealmente, esto toma un viaje de ida y vuelta. El segundo paso es la conexión TCP. Una vez que el navegador tiene la dirección IP del servidor, necesita establecer una conexión con el servidor detrás de esa dirección. Esto implica un viaje de ida y vuelta. Entonces, un ping al servidor y luego una respuesta del servidor. Entonces, si hay un retraso de 100 milisegundos entre el cliente y el servidor, esto va a tomar 200 milisegundos. Y el tercer paso es el handshake TLS. Una vez que el navegador se ha conectado al servidor, necesita encriptar la conexión para actualizar HTTP a HTTPS, y esto lleva dos viajes de ida y vuelta más. Entonces, establecer una conexión tiene estos tres pasos y en una conexión 4G típica, estos pasos suelen tardar 500, 600 milisegundos en completarse, como en esta cascada.

Entonces, en este caso, lo que sucedió fue que al agregar una CDN, también accidentalmente agregamos el retraso de conexión porque la CDN estaba en un dominio separado y como resultado de eso, retrasamos los archivos CSS que la página utiliza en 600 milisegundos y como la página no puede renderizarse sin CSS, la primera pintura de contenido también se retrasó. Entonces, movimos los archivos CSS a la CDN, los archivos CSS se retrasaron, la primera pintura de contenido ocurrió tarde. ¿Correcto? Entonces, en ese momento, en realidad no descubrimos qué sucedió, así que tuvimos que abandonar la optimización de la CDN. Hoy, afortunadamente, sé cómo solucionar esto, sé cómo evitar esto.

3. CDN Optimization and Code Splitting

Short description:

Para optimizar la CDN y evitar costos de conexión, utiliza una CDN de extracción para todo el origen. Archivos populares como Google Fonts ya no se almacenan en caché en diferentes sitios debido a la partición de caché. Cargar todo desde tu propio origen es crucial para evitar retrasos de conexión. Otra optimización que implementamos fue la división de código.

Entonces, para la optimización de la CDN, para el costo de conexión optimización, para el costo de conexión al fuego de la libreta, debo asegurarme de no agregar nuevos costos de conexión. No agregar nuevos dominios. Y la única forma de hacerlo es colocar una CDN frente a todo el origen, no solo para algunos archivos. El término técnico correcto que quieres usar es CDN de extracción, que es algo que quieres usar en lugar de la CDN de empuje que quieres evitar. Esto es un poco más complicado de configurar que simplemente enviar algunos archivos a un bucket y poner una CDN frente a eso, pero si lo haces, bueno, no vas a tener una regresión de rendimiento, lo cual es bueno.

Ahora, algunos de mis clientes a quienes les presento este problema de costo de conexión tienen una preocupación diferente. Dicen, como, `Oye, Luke, entiendo que hay un costo de conexión, pero en mi caso, uso la fuente Roboto de la CDN de Google Fonts, y es muy popular en muchos sitios. ¿No se almacenará en caché cuando el usuario solo use esos sitios? ¿No evitará completamente el costo de conexión en este caso? Es decir, si un usuario llega a algún sitio que usa Roboto de Google Fonts, el navegador almacenará en caché esa fuente, ¿verdad? Y si cinco minutos después el usuario llega a mi sitio, que también usa Roboto de Google Fonts, el navegador tomará la fuente de la caché y el archivo estará disponible de inmediato sin ningún retraso de conexión, ¿verdad? La respuesta es no. Hace un tiempo, esto funcionaba como lo describí. Sin embargo, hace unos años, esto cambió. A finales de 2020, Chrome lanzó algo llamado partición de caché. La idea de la partición de caché es que cada archivo que el navegador almacena en caché se almacena solo para ese sitio. Entonces, si tienes otro sitio.com solicitando una robot.font, ese archivo se almacenará en caché en el bucket de otro sitio.com. Si tienes mi sitio.com también solicitando la robot.font, ese archivo se almacenará en caché en el bucket de mi sitio.com. No se tomará del otro sitio.com. Esto se hace por razones de privacidad. Y se ha implementado en todas partes desde principios de 2021. Entonces, si estás pensando, pero estoy cargando un archivo popular, probablemente se almacenará en caché desde otros sitios, no lo hará. Para que los costos de conexión no se vuelvan en tu contra, debes cargar todo desde tu propio origen. Incluso cosas como Google Fonts. En general, la regla general con las CDNs y los dominios es que todo debe estar detrás del mismo dominio. Mientras sigas esta regla, deberías estar bien. Si te alejas de esta regla, te volverá en tu contra. Esta es la primera optimización.

Ahora, hablemos de otra optimización, la división de código. ¿Quién aquí ha hecho división de código en sus proyectos antes? Vale, sí, mucha gente. Eso es como un meta de los separadores de código anónimos. Así que cuando estaba trabajando en la aplicación, la respuesta no fue lo único que intentamos para que la aplicación fuera más rápida. Otra optimización que intentamos fue la división de código. Al comienzo de la ronda de optimización, nuestro paquete se veía más o menos así.

4. Code Splitting and Delayed Rendering

Short description:

Intentamos resolver el problema de agrupar todas las rutas en dos fragmentos mediante la implementación de la división de código. Si bien el tamaño del paquete disminuyó, la aplicación tardó más en renderizarse, con un retraso de dos segundos. Los primeros elementos de la interfaz de usuario aparecieron más rápido, pero la renderización general de la interfaz de usuario se retrasó.

Teníamos cuatro o cinco rutas independientes separadas, cada una de ellas con sus propios componentes, sus propias dependencias. Pero todas estas rutas se agrupaban en solo dos fragmentos, el fragmento principal y el fragmento del proveedor, diez megabytes en total.

Entonces, ¿qué intentamos hacer para resolver esto? Por supuesto, intentamos la división de código. Nuestra aplicación de una sola página se construyó a partir de un único punto de entrada, tenía varias rutas y utilizaba el enrutador de React para seleccionar la ruta correcta para servir. Si buscas guías de división de código para el enrutador de React o el enrutador de Vista, ambos te recomendarán prácticamente lo mismo. Toma tu componente raíz, envuélvelo con importaciones y divídelo en fragmentos de código. Eso es precisamente lo que hicimos.

Y así lo hicimos, revisamos nuestro paquete y notamos que definitivamente se estaba volviendo más pequeño, como en lugar de servir todo el paquete de diez megabytes de inmediato, ahora podemos cargar solo cinco megabytes de código. ¡Hurra! Sin embargo, una vez que ejecutamos las pruebas de performance, nos dimos cuenta de que la aplicación ahora tarda más en renderizarse. Los primeros elementos de la interfaz de usuario aparecen más rápido, pero la interfaz de usuario completa se renderiza dos segundos después.

5. Code Splitting and Performance

Short description:

Para solucionar este problema, analicemos el portafolio de red. El portafolio original solicita index.html y los archivos y paquetes asociados. Después de ejecutar el paquete y enviar solicitudes a la API, se renderiza la aplicación. Sin embargo, la división de código introduce una cascada de solicitudes, retrasando el proceso de renderizado. A pesar de reducir el tamaño del paquete, el rendimiento de la aplicación empeora. Para evitar esto, frameworks como Next.js y Nuke.js manejan la división de código de manera diferente, construyendo paquetes separados para cada ruta y gestionando el intercambio de código.

¿Alguien ha visto algo así antes? No, no hay manos. Entonces, para debug este problema, volvamos a analizar el portafolio de red. Este es el portafolio original. Veamos qué sucede aquí. Primero, solicitamos index.html. Cuando llega index.html, solicitamos los archivos a los que hace referencia y nuestros paquetes. Cuando llega el paquete, hay una pausa en las solicitudes de red porque ejecutamos el paquete. Puedes ver esto por esta ejecución JS en rosa, rectángulos delgados. Y una vez que la ejecución de JS se completa, enviamos algunas solicitudes a la API. Y una vez que eso se completa, renderizamos la aplicación. Puedes ver esto por esta barra vertical discontinua en verde que indica la mayor pintura de consola en WebPageTest.

Ahora, este es el nuevo flujo, el que creamos. Esto es lo que sucede aquí. Nuevamente solicitamos index.html. Cuando llega index.html, solicitamos el paquete y CSS, prácticamente como la vez anterior. Cuando llega el paquete, ejecutamos el paquete. Pero ahora, cuando el paquete termina de ejecutarse, solicitamos otro conjunto de archivos JavaScript, los fragmentos para la raíz dividida por código que la aplicación necesita renderizar ahora. Hemos dividido nuestro punto de entrada y ahora la aplicación debe descargar la raíz para renderizar, pero no sabe que necesita esa raíz hasta que tenga el paquete principal. Por lo tanto, la aplicación solo puede renderizar después de que se hayan descargado y ejecutado estos fragmentos divididos por código, lo que ocurre dos o tres segundos después. Al dividir el código de la aplicación, básicamente hicimos que nuestro paquete fuera más pequeño, pero también introdujimos una cascada de solicitudes. En lugar de cargar todo de una vez, todo el código que la aplicación necesita, ahora lo hacemos en múltiples pasadas. Y a pesar de que el código se vuelve más pequeño, el rendimiento de la aplicación en realidad empeora. Este fue un error que cometimos en ese momento, y hoy en día sigue siendo un problema bastante común que veo en las aplicaciones con las que trabajo. Tampoco ayuda que las guías oficiales recomienden esta solución. Entonces, para evitar que esto se vuelva en nuestra contra, puedes hacer una de estas cosas. Primero, puedes usar Next.js o Nuke.js o si usas Angular no sé qué podemos usar. Estos frameworks hacen la división de código por ti y abordan la división de código de manera diferente. En lugar de usar esta función de importación dinámica para cargar las rutas actuales, construyen un paquete separado para cada ruta y gestionan el intercambio de código entre cada paquete. Así que prácticamente tienes todo hecho por ti.

6. Optimización de la división de código

Short description:

Para optimizar la división de código, utiliza la importación solo para componentes perezosos que no afecten la primera renderización. Para componentes críticos como los componentes raíz, evita usar la importación. En su lugar, utiliza múltiples puntos para evitar que la aplicación se vuelva más lenta.

Esta es la opción uno. Opción dos, teóricamente también puedes replicar lo que hacen estos frameworks por tu cuenta. No voy a decir cómo hacerlo, porque no sé cómo hacerlo. Pero si te metes en el código fuente y configuras estos complementos de Webpack y también consultas este artículo de inmersión más profunda, al que he enlazado y obtendrás en... Está disponible en este enlace que se muestra en todas partes. Es posible que puedas configurar algo. Nunca he hecho esto, sinceramente. Espero no tener que hacerlo nunca. Pero la opción tres es si ya tienes mucho código que utiliza importaciones dinámicas para rutas y no te apetece migrar a Next.js, aún hay una forma de solucionarlo. Lo que puedes intentar hacer es analizar los pasos de compilación de Webpack y detectar qué fragmentos necesita cada ruta. Y luego generar múltiples archivos HTML con los enlaces relevantes de pre-carga de fragmentos para cada ruta para que cada ruta comience a precargar sus fragmentos necesarios de antemano. Es bastante complicado de hacer. Suena complicado. Es complicado de hacer. Pero he enlazado un caso en el que tuve que implementar esto para un cliente de código abierto con mucha documentación. Así que si te encuentras en esta situación, también puedes echarle un vistazo. De todos modos, la idea clave, la regla general aquí es que la próxima vez que decidas dividir el código algo, utiliza la importación solo para componentes perezosos, para componentes que no afecten la primera renderización. Tal vez sea un componente de modelo, tal vez sea algo que no sea visible para el usuario de inmediato. Para componentes críticos como tus componentes raíz, como componentes en los que la aplicación depende, no utilices la importación. Utiliza múltiples puntos, o la división hará que tu aplicación sea más lenta y se vuelva en tu contra.

7. Imágenes con carga diferida y rendimiento

Short description:

La carga diferida de imágenes puede causar problemas de rendimiento si se aplica de manera demasiado agresiva. Al cargar imágenes de forma diferida, pueden producirse retrasos debido al bloqueo de CSS. El navegador espera a que se cargue el CSS antes de descargar las imágenes diferidas, lo que provoca un retraso en su tiempo de carga. Para evitar esto, especifica atributos de prioridad en las imágenes críticas y utiliza herramientas como la extensión web vitals para detectar y optimizar el elemento de pintado de contenido más grande (LCP).

Muy bien. Hablemos de otra optimización, que es la carga diferida de imágenes. Este es en realidad un ejemplo que doy a los asistentes en mi masterclass, y aquí hay una página de producto simple. Esta página muestra una lista de 100 productos, cada uno de estos productos tiene una imagen. Cuando abres la página, la página carga inmediatamente 100 imágenes. ¿Cómo podrías solucionar esto? En realidad, ¿cómo podrías solucionar esto? ¿Cómo podrías solucionar esto? ¡Sí, carga diferida! Muchos de los asistentes a mi masterclass identifican correctamente que lo que necesitan hacer es hacer que esta imagen se cargue de forma diferida. Lo que hacen es encontrar el componente que renderiza cada tarjeta de producto y añadir el atributo lazy loading, que le indica al navegador que evite cargar esta imagen hasta que entre en el viewport. Luego verifican DevTools y confirman que, sí, parece que el problema se ha resuelto. Ahora estamos cargando nueve imágenes antes de desplazarnos hacia abajo. Parece bastante efectivo, ¿verdad? Pero nuevamente, si observas los resultados de Lighthouse antes y después, descubrirás que el LCP del sitio en realidad empeoró. ¿Por qué? Para averiguar por qué, tendrás que desplazarte hacia abajo en el informe y ver cuál fue exactamente el elemento de pintado de contenido más grande (LCP), el elemento que activó el más grande en la página. El elemento de pintado de contenido más grande fue esta imagen, shell-gold-some-hash.jpg. Y una vez que sepas cuál fue el elemento de pintado de contenido más grande, debes mirar la cascada y ver qué ha cambiado exactamente en la carga de esa imagen. Entonces, si miras la cascada, verás que antes de aplicar la carga diferida, esa imagen comenzó a cargarse alrededor del segundo 0.8. Mientras que después de aplicar la carga diferida, esta imagen comenzó a cargarse en el segundo 1.6, en realidad en el segundo 1.7. Aquí está, es la misma imagen. Pero, ¿por qué exactamente sucede esto? Entonces, si vuelves a verificar el elemento LCP, notarás que el elemento LCP, la imagen LCP, tiene este atributo Loading Lazy porque aplicamos Loading Lazy a todas las tarjetas de producto. Y algunas de las tarjetas de producto eran en realidad elementos LCP. Resulta que las imágenes con carga diferida no se retrasan solo porque sean lentas o algo así, sino que se retrasan por razones técnicas. Se retrasan porque están bloqueadas por CSS. Cuando tienes una imagen con carga diferida, el navegador no puede descargar la imagen hasta que sepa si la imagen está dentro del viewport. Y esto lo controla CSS. Tu CSS puede tener cualquiera de estas reglas y el navegador no sabrá qué reglas tiene hasta que realmente tenga el CSS, por lo que antes de que el navegador pueda descargar las imágenes con carga diferida, antes de que el navegador sepa si estas imágenes están dentro del viewport, tiene que esperar a que se cargue el CSS. Y eso es lo que sucedió aquí. Aplicamos la carga diferida y las imágenes tuvieron que esperar a que se cargara el CSS, lo que provocó que comenzaran a cargarse casi un segundo más tarde y se retrasaran. Entonces, así es como al aplicar la carga diferida de forma demasiado agresiva, en realidad perjudicamos nuestro rendimiento. Ahora, nuevamente, ¿cómo evitar que esto se vuelva en nuestra contra? Primero, si utilizas el componente de imagen de Next.js o la imagen optimizada de Angular, una cosa que debes recordar es que estos componentes utilizan la carga diferida de forma predeterminada. Entonces, si tomas una imagen crítica y la envuelves con la imagen de Next.js y la colocas en la parte superior de la página y resulta ser el elemento LCP, retrasará tu LCP. Entonces, lo que debes hacer es recordar especificar atributos de prioridad verdaderos en las imágenes críticas para que se carguen lo antes posible. Y segundo, para detectar las imágenes críticas, una cosa que me gusta hacer es instalar la extensión web vitals, habilitar el inicio de sesión en la consola en sus opciones y hacerlo un hábito verificar el elemento LCP del sitio en el que estoy trabajando. Entonces, si instalo esta extensión y habilito el inicio de sesión en la consola, lo que la extensión comenzará a hacer es registrar toda esta información en la consola.

QnA

Optimización de imágenes y división de código

Short description:

Si una imagen tiene el atributo load y lazy, puede ser un peligro para el elemento de pintado de contenido más grande (LCP). Siguiendo la regla general, las imágenes por encima del pliegue no deben tener el atributo load y lazy para evitar que la optimización de imágenes se vuelva en contra. Ivan Akulov, un experto desarrollador de Google, compartió este consejo. También mencionó su cuenta de Twitter donde publica datos curiosos sobre rendimiento. Ivan expresó su gratitud por la oportunidad de hablar y abrió el espacio para preguntas. Una pregunta fue sobre la herramienta utilizada para generar gráficos de cascada, a lo que Ivan respondió webpagetest.org. Otra pregunta fue sobre el impacto de la división excesiva de código en el rendimiento. Ivan mencionó una posible ralentización al tener más de 30 o 40 fragmentos de JavaScript, pero no tenía información detallada sobre el tema.

Y si estoy trabajando en algún sitio y veo que el elemento LCP es una imagen y noto que la imagen tiene el atributo load y lazy, entonces sé que estoy en peligro. Ese es el segundo punto. Y en general, recuerda la regla general. Todas las imágenes por encima del pliegue no deben tener load y lazy, siempre y cuando sigas esta regla, de lo contrario, la optimización de imágenes no funcionará correctamente.

Así que gracias. Esto fue Ivan Akulov, soy un experto desarrollador de Google. Tengo Twitter donde publico datos curiosos sobre rendimiento. Tal vez quieras suscribirte. Sin presiones, amigos. Y gracias por recibirme.

Tenemos unos minutos para algunas preguntas, porque también recibimos algunas. Muy bien, veamos las preguntas. ¿Qué herramienta utilizas para generar estos gráficos de cascada? Es webpagetest.org. Esa es la respuesta. Así es. Es genial. Sí, me encanta. Es genial. Eso es lo que la gente debería usar. Muy bien. ¿Es posible que demasiados fragmentos, demasiada división de código, en realidad empeoren el rendimiento? Demasiada división de código. Bueno... Mientras evites esa caída de velocidad que compartí, probablemente no. Una cosa que leí en Twitter de Ado's money en algún momento es que... Pero es información de 2020, así que podría haber cambiado. Cuando tienes más de 30 o 40 fragmentos de JavaScript, entonces los costos de comunicación entre procesos comienzan a aparecer. Sé que en general todo comienza a volverse más lento. Pero no tengo idea de los detalles, tal vez solo lo recuerdo mal. Ya veo.

Encabezados Link, Pre-connect y Pre-load

Short description:

Los encabezados Link, pre-connect y pre-load pueden ayudar con las conexiones y las cascadas de carga, pero solo si cargas tus archivos más tarde. Si haces referencia a un dominio de terceros desde tu HTML, estos encabezados no ayudarán porque también llegan a tu HTML y el navegador comienza a conectarse al dominio de terceros tan pronto como recibe el HTML. No ayudan significativamente con cosas críticas.

En general, tener 100 archivos puede ser una idea complicada. Muy bien. Déjame ver. ¿Cuánto ayudan los encabezados Link, pre-connect y pre-load con... Oh, se fue. Oh, no, no se fue. Ayudan con las conexiones y las cascadas de carga. Oh, en realidad es una gran pregunta. Pueden ayudar, pero solo si cargas tus archivos más tarde. No estoy seguro... ¿Puedo mostrar mis diapositivas aún? No. No, no. No. Ahora es difícil. De acuerdo. Entonces, si tienes algo... Básicamente, si haces referencia a un dominio de terceros desde tu HTML, los encabezados Link, pre-connect y pre-load no te ayudarán en absoluto, porque también llegarán a tu HTML. Y el navegador comenzará a conectarse al dominio de terceros tan pronto como reciba el HTML. Así que no puedes acelerar esto. Bueno, tal vez puedas con el estándar HTTP 103 early hints, pero eso es algo avanzado. En general, no ayudan mucho con cosas críticas. Muy bien. ¿Uno más? Recursos recomendados sobre cómo mejorar el conocimiento de rendimiento. Me preguntaron esto en Twitter hace dos días. Tuitearé la respuesta. Sí, eso es. Hay algunos. Tal vez repite tu nombre de usuario de Twitter para que la gente pueda ir a tu Twitter y echar un vistazo a ellos. Oh, sí. En I am, Akulov, mi apellido. Perfecto. Gracias. Creo que es todas las preguntas que responderé. Demos un cálido aplauso una vez más.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar
JSNation 2022JSNation 2022
21 min
The Future of Performance Tooling
Top Content
Our understanding of performance & user-experience has heavily evolved over the years. Web Developer Tooling needs to similarly evolve to make sure it is user-centric, actionable and contextual where modern experiences are concerned. In this talk, Addy will walk you through Chrome and others have been thinking about this problem and what updates they've been making to performance tools to lower the friction for building great experiences on the web.
React Advanced Conference 2023React Advanced Conference 2023
22 min
Power Fixing React Performance Woes
Next.js and other wrapping React frameworks provide great power in building larger applications. But with great power comes great performance responsibility - and if you don’t pay attention, it’s easy to add multiple seconds of loading penalty on all of your pages. Eek! Let’s walk through a case study of how a few hours of performance debugging improved both load and parse times for the Centered app by several hundred percent each. We’ll learn not just why those performance problems happen, but how to diagnose and fix them. Hooray, performance! ⚡️

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
JSNation 2023JSNation 2023
170 min
Building WebApps That Light Up the Internet with QwikCity
Featured WorkshopFree
Building instant-on web applications at scale have been elusive. Real-world sites need tracking, analytics, and complex user interfaces and interactions. We always start with the best intentions but end up with a less-than-ideal site.
QwikCity is a new meta-framework that allows you to build large-scale applications with constant startup-up performance. We will look at how to build a QwikCity application and what makes it unique. The workshop will show you how to set up a QwikCitp project. How routing works with layout. The demo application will fetch data and present it to the user in an editable form. And finally, how one can use authentication. All of the basic parts for any large-scale applications.
Along the way, we will also look at what makes Qwik unique, and how resumability enables constant startup performance no matter the application complexity.
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
React Advanced Conference 2023React Advanced Conference 2023
148 min
React Performance Debugging
Workshop
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Summit 2022React Summit 2022
50 min
High-performance Next.js
Workshop
Next.js is a compelling framework that makes many tasks effortless by providing many out-of-the-box solutions. But as soon as our app needs to scale, it is essential to maintain high performance without compromising maintenance and server costs. In this workshop, we will see how to analyze Next.js performances, resources usage, how to scale it, and how to make the right decisions while writing the application architecture.
Vue.js London 2023Vue.js London 2023
49 min
Maximize App Performance by Optimizing Web Fonts
WorkshopFree
You've just landed on a web page and you try to click a certain element, but just before you do, an ad loads on top of it and you end up clicking that thing instead.
That…that’s a layout shift. Everyone, developers and users alike, know that layout shifts are bad. And the later they happen, the more disruptive they are to users. In this workshop we're going to look into how web fonts cause layout shifts and explore a few strategies of loading web fonts without causing big layout shifts.
Table of Contents:What’s CLS and how it’s calculated?How fonts can cause CLS?Font loading strategies for minimizing CLSRecap and conclusion