Comprende la visión detrás del componente de secuencia de comandos de Next.js, que proporciona una solución integrada para optimizar la carga de secuencias de comandos de terceros.
Alrededor del 45% de las solicitudes de sitios web que se publican en dispositivos móviles y computadoras son solicitudes de terceros, de las cuales el 33% son secuencias de comandos. El tamaño, la latencia y la carga de secuencias de comandos de terceros pueden afectar significativamente el rendimiento de un sitio. El componente de secuencia de comandos de Next.js incluye prácticas recomendadas integradas y valores predeterminados para ayudar a los desarrolladores a incorporar secuencias de comandos de terceros en sus aplicaciones y, al mismo tiempo, abordar posibles problemas de rendimiento de forma inmediata.
Secuencias de comandos de terceros y su impacto en el rendimiento
Las secuencias de comandos de terceros permiten a los desarrolladores web aprovechar las soluciones existentes para implementar funciones comunes y reducir el tiempo de desarrollo. Sin embargo, los creadores de estas secuencias de comandos no suelen tener ningún incentivo para considerar el impacto en el rendimiento del sitio web de consumo. Estas secuencias de comandos también son una caja negra para los desarrolladores que las utilizan.
Las secuencias de comandos representan una cantidad significativa de bytes de terceros que descargan los sitios web en diferentes categorías de solicitudes de terceros. De forma predeterminada, el navegador prioriza las secuencias de comandos según su ubicación en el documento, lo que puede retrasar el descubrimiento o la ejecución de secuencias de comandos fundamentales para la experiencia del usuario.
Las bibliotecas de terceros requeridas para el diseño deben cargarse antes para renderizar la página. Los terceros que no son necesarios para la renderización inicial deben diferirse para que no bloqueen otro procesamiento en el subproceso principal. Lighthouse tiene dos auditorías para marcar las secuencias de comandos que bloquean la renderización o que bloquean el subproceso principal.
Es importante considerar la secuencia de carga de recursos de tu página para que los recursos críticos no se retrasen y los recursos no críticos no los bloqueen.
Si bien existen prácticas recomendadas para reducir el impacto de los terceros, es posible que no todos sepan cómo implementarlas para cada tercero que usan. Esto puede ser complicado por los siguientes motivos:
- En promedio, los sitios web utilizan entre 21 y 23 terceros diferentes (incluidas las secuencias de comandos) en los dispositivos móviles y las computadoras de escritorio. El uso y las recomendaciones pueden variar para cada uno.
- La implementación de muchos terceros puede diferir según si se usa un framework o una biblioteca de IU en particular.
- Las bibliotecas de terceros más nuevas se presentan con frecuencia.
- Los diversos requisitos comerciales relacionados con la misma plataforma de terceros dificultan que los desarrolladores estandaricen su uso.
El enfoque de Aurora en los guiones de terceros
Parte de la colaboración de Aurora con herramientas y frameworks web de código abierto consiste en proporcionar valores predeterminados sólidos y herramientas bien definidas para ayudar a los desarrolladores a mejorar aspectos de la experiencia del usuario, como el rendimiento, la accesibilidad, la seguridad y la preparación para dispositivos móviles. En 2021, nos enfocamos en ayudar a las pilas de frameworks a mejorar la experiencia del usuario y sus métricas de Métricas web esenciales.
Uno de los pasos más significativos para lograr nuestro objetivo de mejorar el rendimiento del framework consistió en investigar la secuencia de carga ideal de las secuencias de comandos de terceros en Next.js. Los frameworks como Next.js tienen una posición única para proporcionar parámetros de configuración predeterminados y funciones útiles que ayudan a los desarrolladores a cargar recursos de manera eficiente, incluidos los de terceros. Analizamos exhaustivamente los datos de Lighthouse y el Archivo HTTP para descubrir qué terceros bloquean la renderización más en diferentes frameworks.
Para solucionar el problema de que el subproceso principal bloquea secuencias de comandos de terceros que se usan en una aplicación, compilamos el componente de secuencias de comandos. El componente encapsula las funciones de secuenciación para proporcionar a los desarrolladores mejores controles para la carga de secuencias de comandos de terceros.
Secuenciar secuencias de comandos de terceros sin un componente de framework
La guía disponible para reducir el impacto de las secuencias de comandos que bloquean el procesamiento proporciona los siguientes métodos para cargar y secuenciar secuencias de comandos de terceros de manera eficiente:
Usa el atributo
async
odefer
con etiquetas<script>
que le indiquen al navegador que cargue secuencias de comandos de terceros no críticas sin bloquear el analizador de documentos. Las secuencias de comandos que no son necesarias para la carga inicial de la página o la primera interacción del usuario se pueden considerar no esenciales.<script src="https://example.com/script1.js" defer></script> <script src="https://example.com/script2.js" async></script>
Establece conexiones anticipadas con los orígenes requeridos mediante preconnect y dns-prefetch. Esto permite que las secuencias de comandos críticas comiencen a descargarse antes.
<head> <link rel="preconnect" href="http://PreconnThis.com"> <link rel="dns-prefetch" href="http://PrefetchThis.com"> </head>
Carga diferida de recursos y elementos incorporados de terceros después de que se haya terminado de cargar el contenido de la página principal o cuando el usuario se desplaza hacia abajo hasta la parte de la página en la que se incluyen.
El componente de secuencia de comandos de Next.js
El componente de secuencia de comandos de Next.js implementa los métodos anteriores para secuenciar secuencias de comandos y proporciona una plantilla para que los desarrolladores definan su estrategia de carga. Una vez que se especifique la estrategia adecuada, se cargará de forma óptima sin bloquear otros recursos esenciales.
El componente de secuencia de comandos se basa en la etiqueta <script> HTML y proporciona una opción para establecer la prioridad de carga de secuencias de comandos de terceros con el atributo strategy.
// Example for beforeInteractive:
<Script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" />
// Example for afterInteractive (default):
<Script src="https://example.com/samplescript.js" />
// Example for lazyonload:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" />
El atributo strategy puede tener tres valores.
beforeInteractive
: Esta opción se puede usar para secuencias de comandos críticas que deben ejecutarse antes de que la página se vuelva interactiva. Next.js garantiza que esas secuencias de comandos se inserten en el HTML inicial del servidor y se ejecuten antes que otros JavaScript empaquetados por sí mismos. La administración de consentimiento, las secuencias de comandos de detección de bots o las bibliotecas de ayuda necesarias para renderizar contenido importante son buenas opciones para esta estrategia.afterInteractive
: Esta es la estrategia predeterminada que se aplica y equivale a cargar una secuencia de comandos con el atributo aplazar. Se debe usar para las secuencias de comandos que el navegador puede ejecutar después de que la página es interactiva, por ejemplo, las secuencias de comandos de estadísticas. Next.js inserta estas secuencias de comandos en el lado del cliente y se ejecutan después de que se hidrata la página. Por lo tanto, a menos que se especifique lo contrario, Next.js aplaza todas las secuencias de comandos de terceros definidas con el componente de secuencia de comandos, lo que proporciona una configuración predeterminada sólida.lazyOnload
: Esta opción se puede usar para cargar de forma diferida secuencias de comandos de baja prioridad cuando el navegador está inactivo. La funcionalidad que proporcionan estas secuencias de comandos no es necesaria inmediatamente después de que la página se vuelve interactiva (por ejemplo, los complementos de chat o redes sociales).
Los desarrolladores pueden indicarle a Next.js cómo su aplicación usa una secuencia de comandos especificando la estrategia. Esto permite que el framework aplique optimizaciones y prácticas recomendadas para cargar la secuencia de comandos y, al mismo tiempo, garantizar la mejor secuencia de carga.
Con el componente de secuencia de comandos, los desarrolladores pueden colocar una secuencia de comandos de terceros en cualquier lugar de la aplicación para los terceros que se cargan tarde y a nivel del documento para las secuencias de comandos críticas. Esto implica que el componente de secuencia de comandos puede estar ubicado en la misma ubicación que el componente que usa la secuencia de comandos. Después de la hidratación, la secuencia de comandos se insertará en la parte superior del documento renderizado inicialmente o en la parte inferior del cuerpo, según la estrategia que se use.
Cómo medir el impacto
Usamos las plantillas de la app de comercio y el blog de partida de Next.js para crear dos apps de demostración que ayudaron a medir el impacto de incluir secuencias de comandos de terceros. Los terceros de uso general para Google Tag Manager y las incorporaciones de redes sociales se incluían en las páginas de estas apps directamente al principio y, luego, a través del componente de secuencia de comandos. Luego, comparamos el rendimiento de estas páginas en WebPageTest.
Secuencias de comandos de terceros en una app de comercio de Next.js
Se agregaron secuencias de comandos de terceros a la plantilla de la app de comercio para la demostración, como se indica a continuación.
En la siguiente comparación, se muestra el progreso visual de ambas versiones del kit de partida de comercio de Next.js. Como se ve, el LCP ocurre casi 1 segundo antes con el componente de secuencia de comandos habilitado con la estrategia de carga correcta.
Secuencias de comandos de terceros en un blog de Next.js
Las secuencias de comandos de terceros se agregaron a la app del blog de demostración como se indica a continuación.
Antes | Después |
---|---|
Google Tag Manager con asíncrono | Componente de secuencia de comandos con strategy = lazyonload para cada una de las cuatro secuencias de comandos |
Botón Seguir de Twitter con asíncrono | |
Botón de suscripción de YouTube sin async o defer | |
Botón Seguir de LinkedIn sin async o aplazar |
Como se ve en el video, el primer procesamiento de imagen con contenido (FCP) ocurre a los 0.9 segundos en la página sin el componente de secuencia de comandos y a los 0.4 segundos con el componente de secuencia de comandos.
Qué sigue para el componente de secuencia de comandos
Si bien las opciones de estrategia para afterInteractive
y lazyOnload
proporcionan un control significativo sobre las secuencias de comandos que bloquean la renderización, también estamos explorando otras opciones que aumentarían la utilidad del componente de secuencia de comandos.
Usa trabajadores web
Los trabajadores web se pueden usar para ejecutar secuencias de comandos independientes en subprocesos en segundo plano que pueden liberar el subproceso principal para controlar el procesamiento de tareas de la interfaz de usuario y mejorar el rendimiento. Los Web Workers son más adecuados para transferir el procesamiento de JavaScript, en lugar del trabajo de la IU, del subproceso principal. Las secuencias de comandos que se usan para asistencia al cliente o marketing, que no suelen interactuar con la IU, pueden ser buenas candidatas para ejecutarse en un subproceso en segundo plano. Se puede usar una biblioteca de terceros liviana (PartyTown) para aislar esas secuencias de comandos en un trabajador web.
Con la implementación actual del componente de secuencia de comandos de Next.js, te recomendamos que dejes en suspenso estas secuencias de comandos en el subproceso principal configurando la estrategia en afterInteractive
o lazyOnload
. En el futuro, proponemos incorporar una nueva opción de estrategia, 'worker'
, que permitirá que Next.js use PartyTown o una solución personalizada para ejecutar secuencias de comandos en los trabajadores web. Aceptamos los comentarios de los desarrolladores sobre esta RFC.
Minimiza el CLS
Los elementos incorporados de terceros, como los anuncios, los videos o los feeds de redes sociales, pueden causar cambios de diseño cuando se cargan de forma diferida. Esto afecta la experiencia del usuario y la métrica de Cambio de diseño acumulado (CLS) de la página. Para minimizar el CLS, especifica el tamaño del contenedor en el que se cargará la incorporación.
El componente de secuencia de comandos se puede usar para cargar incorporaciones que pueden provocar cambios de diseño. Estamos considerando aumentarlo para proporcionar opciones de configuración que ayuden a reducir el CLS. Esto puede estar disponible dentro del propio componente Script o como un componente complementario.
Componentes de wrapper
La sintaxis y la estrategia de carga para incluir secuencias de comandos de terceros populares, como Google Analytics o Google Tag Manager (GTM), suelen ser fijas. Estos se pueden encapsular aún más en componentes de wrapper individuales para cada tipo de secuencia de comandos. Solo un conjunto mínimo de atributos específicos de la aplicación (como el ID de seguimiento) estará disponible para los desarrolladores. Los componentes wrapper ayudarán a los desarrolladores con las siguientes tareas:
- Incluir etiquetas de secuencias de comandos populares será más fácil.
- Garantizar que el framework use la estrategia más óptima en segundo plano
Conclusión
Por lo general, las secuencias de comandos de terceros se crean para incluir funciones específicas en el sitio web de consumo. Para reducir el impacto de las secuencias de comandos no críticas, te recomendamos que las difieras, lo que el componente de secuencia de comandos de Next.js hace de forma predeterminada. Los desarrolladores tienen la seguridad de que las secuencias de comandos incluidas no retrasarán la funcionalidad crítica, a menos que apliquen de forma explícita la estrategia beforeInteractive
. Al igual que el componente de secuencias de comandos de Next.js, los desarrolladores de marcos de trabajo también pueden considerar compilar estas funciones en otros frameworks. Estamos explorando activamente conseguir un componente similar con el equipo de Nuxt.js. En función de los comentarios, también esperamos mejorar el componente de secuencia de comandos para abarcar casos de uso adicionales.
Agradecimientos
Gracias a Kara Erickson, Janicklas Ralph, Katie Hempenius, Philip Walton, Jeremy Wagner y Addy Osmani por sus comentarios sobre esta publicación.