Carga eficientemente JavaScript de terceros

Si una secuencia de comandos de terceros ralentiza la carga de la página, tienes dos opciones para mejorar el rendimiento:

  • Quítala si no agrega valor claro a tu sitio.
  • Optimiza el proceso de carga.

En esta publicación, se explica cómo optimizar el proceso de carga de secuencias de comandos de terceros con las siguientes técnicas:

  • Usa el atributo async o defer en las etiquetas <script>
  • Cómo establecer conexiones anticipadas con los orígenes necesarios
  • Carga diferida
  • Cómo optimizar la entrega de secuencias de comandos de terceros

Usa async o defer

Debido a que las secuencias de comandos síncronas retrasan la construcción y la renderización del DOM, siempre debes cargar secuencias de comandos de terceros de forma asíncrona, a menos que la secuencia de comandos se deba ejecutar antes de que se pueda renderizar la página.

Los atributos async y defer le indican al navegador que puede seguir analizando el código HTML mientras carga la secuencia de comandos en segundo plano y, luego, ejecutarla después de que se cargue. De esta manera, las descargas de secuencias de comandos no bloquean la construcción del DOM ni la renderización de la página, lo que permite que el usuario vea la página antes de que se carguen todas las secuencias de comandos.

<script async src="script.js">

<script defer src="script.js">

La diferencia entre los atributos async y defer es cuándo el navegador ejecuta las secuencias de comandos.

async

Las secuencias de comandos con el atributo async se ejecutan a la primera oportunidad después de que terminan de descargarse y antes del evento load de la ventana. Esto significa que es posible (y probable) que las secuencias de comandos de async no se ejecuten en el orden en que aparecen en el HTML. También significa que pueden interrumpir la compilación del DOM si terminan la descarga mientras el analizador aún está en funcionamiento.

Diagrama de la secuencia de comandos de bloqueo del analizador con el atributo async
Las secuencias de comandos con async aún pueden bloquear el análisis de HTML.

defer

Las secuencias de comandos con el atributo defer se ejecutan después de que se completa el análisis de HTML, pero antes del evento DOMContentLoaded. defer garantiza que las secuencias de comandos se ejecuten en el orden en que aparecen en el HTML y no bloqueen el analizador.

Diagrama del flujo del analizador con una secuencia de comandos con el atributo aplazar
Las secuencias de comandos con defer esperan a ejecutarse hasta que el navegador termine de analizar el HTML.
  • Usa async si es importante que la secuencia de comandos se ejecute antes en el proceso de carga.
  • Usa defer para recursos menos importantes, como un reproductor de video que está debajo de la mitad inferior de la pantalla.

El uso de estos atributos puede acelerar significativamente la carga de la página. Por ejemplo, Telegraph aplazó todas sus secuencias de comandos, incluidos los anuncios y las estadísticas, y mejoró el tiempo de carga de los anuncios en un promedio de cuatro segundos.

Establece conexiones anticipadas con los orígenes necesarios

Puedes ahorrar entre 100 y 500 ms si estableces conexiones anticipadas con orígenes externos importantes.

Dos tipos de <link>, preconnect y dns-prefetch, pueden ayudarte aquí:

preconnect

<link rel="preconnect"> le indica al navegador que tu página desea establecer una conexión con otro origen y que deseas que el proceso comience lo antes posible. Cuando el navegador solicita un recurso del origen conectado previamente, la descarga comienza de inmediato.

<link rel="preconnect" href="https://cdn.example.com">

dns-prefetch

<link rel="dns-prefetch> controla un subconjunto pequeño de lo que controla <link rel="preconnect">. Establecer una conexión implica la búsqueda de DNS y el protocolo de enlace TCP, y para los orígenes seguros, las negociaciones de TLS. dns-prefetch le indica al navegador que solo resuelva el DNS de un dominio específico antes de que se lo llame de forma explícita.

La sugerencia preconnect se usa mejor solo para las conexiones más importantes. Para los dominios de terceros menos importantes, usa <link rel=dns-prefetch>.

<link rel="dns-prefetch" href="http://example.com">

La compatibilidad del navegador con dns-prefetch es ligeramente diferente de la compatibilidad con preconnect, por lo que dns-prefetch puede servir como resguardo para los navegadores que no admiten preconnect. Usa etiquetas de vínculo separadas para implementar esto de forma segura:

<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">

Carga diferida de recursos de terceros

Los recursos de terceros incorporados pueden ralentizar significativamente la carga de la página si están mal construidos. Si no son fundamentales o están en la mitad inferior de la página (es decir, si los usuarios tienen que desplazarse para verlos), la carga diferida es una buena manera de mejorar la velocidad de la página y las métricas de pintura. De esta manera, los usuarios obtienen el contenido de la página principal más rápido y tienen una mejor experiencia.

Un diagrama de una página web que se muestra en un dispositivo móvil con contenido desplazable que se extiende más allá de la pantalla. El contenido que está debajo de la mitad inferior de la página está desaturado porque aún no se carga.
Carga el contenido de forma diferida en la mitad inferior de la página.

Un enfoque eficaz es cargar de forma diferida el contenido de terceros después de que se cargue el contenido de la página principal. Los anuncios son un buen candidato para este enfoque.

Los anuncios son una fuente de ingresos importante para muchos sitios, pero los usuarios llegan por el contenido. Si cargas los anuncios de forma diferida y publicas el contenido principal más rápido, puedes aumentar el porcentaje general de visibilidad de un anuncio. Por ejemplo, MediaVine cambió a los anuncios con carga diferida y observó una mejora del 200% en la velocidad de carga de la página. Google Ad Manager tiene documentación sobre cómo cargar anuncios de forma diferida.

También puedes configurar el contenido de terceros para que se cargue solo cuando los usuarios se desplacen por primera vez a esa sección de la página.

Intersection Observer es una API del navegador que detecta de manera eficiente cuándo un elemento entra o sale del viewport del navegador, y puedes usarla para implementar esta técnica. lazysizes es una biblioteca popular de JavaScript para la carga diferida de imágenes y iframes. Admite incorporaciones de YouTube y widgets. También tiene compatibilidad opcional con Intersection Observer.

El uso del atributo loading para la carga diferida de imágenes y iframes es una excelente alternativa a las técnicas de JavaScript y, recientemente, está disponible en Chrome 76.

Optimiza la forma en que publicas secuencias de comandos de terceros

A continuación, se incluyen algunas estrategias recomendadas para optimizar el uso de secuencias de comandos de terceros.

Hosting de CDN de terceros

Es común que los proveedores externos proporcionen URLs para los archivos JavaScript que alojan, por lo general, en una red de distribución de contenido (CDN). Los beneficios de este enfoque son que puedes comenzar rápidamente (solo debes copiar y pegar la URL) y no hay sobrecarga de mantenimiento. El proveedor externo se encarga de la configuración del servidor y de las actualizaciones de secuencias de comandos.

Sin embargo, como no están en el mismo origen que el resto de tus recursos, cargar archivos desde una CDN pública tiene un costo de red. El navegador debe realizar una búsqueda de DNS, establecer una nueva conexión HTTP y, en los orígenes seguros, realizar un protocolo de enlace SSL con el servidor del proveedor.

Cuando usas archivos de servidores de terceros, rara vez tienes control sobre la almacenamiento en caché. Depender de la estrategia de almacenamiento en caché de otra persona puede hacer que las secuencias de comandos se vuelvan a recuperar innecesariamente de la red con demasiada frecuencia.

Autoalojan secuencias de comandos de terceros

La autoalojamiento de secuencias de comandos de terceros es una opción que te brinda más control sobre el proceso de carga de una secuencia de comandos. Si te autoalojas, puedes hacer lo siguiente:

Por ejemplo, Casper logró reducir 1.7 segundos los tiempos de carga a través de la autoalojamiento de una secuencia de comandos de prueba A/B.

Sin embargo, el autoalojamiento tiene un gran inconveniente: las secuencias de comandos pueden quedar desactualizadas y no recibirán actualizaciones automáticas cuando haya un cambio en la API o una corrección de seguridad.

Usa los trabajadores de servicio para almacenar en caché secuencias de comandos de servidores de terceros

Puedes usar trabajadores del servicio para almacenar en caché secuencias de comandos de servidores de terceros como alternativa a la autoalojación. Esto te brinda un mayor control sobre el almacenamiento en caché, mientras conservas los beneficios de las CDN de terceros.

Puedes controlar la frecuencia con la que se vuelven a recuperar las secuencias de comandos de la red y crear una estrategia de carga que limite las solicitudes de recursos de terceros no esenciales hasta que un usuario llegue a una interacción clave en la página. Con preconnect, puedes establecer conexiones anticipadas y también ayudar a mitigar los costos de red.