Carga eficientemente JavaScript de terceros

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

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

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

  • Cómo usar los atributos async o defer en etiquetas <script>
  • Establece conexiones tempranas con los orígenes necesarios
  • Carga diferida
  • Cómo optimizar la publicación de secuencias de comandos de terceros

Usa async o defer

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

Los atributos async y defer le indican al navegador que puede seguir analizando el HTML mientras se 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 el procesamiento de la página, lo que permite que el usuario vea la página antes de que todas las secuencias de comandos terminen de cargarse.

<script async src="script.js">

<script defer src="script.js">

La diferencia entre los atributos async y defer es el momento en que el navegador ejecuta las secuencias de comandos.

async

Las secuencias de comandos con el atributo async se ejecutan en 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 código HTML. También significa que pueden interrumpir la compilación del DOM si terminan de descargarse mientras el analizador aún está en funcionamiento.

Diagrama de la secuencia de comandos que bloquea el analizador con un atributo asíncrono
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 una vez que el análisis de HTML finaliza por completo, pero antes del evento DOMContentLoaded. defer garantiza que las secuencias de comandos se ejecuten en el orden en que aparecen en el código HTML y no bloquea el analizador.

Diagrama del flujo del analizador con una secuencia de comandos con atributo de aplazamiento
Las secuencias de comandos con defer esperan para 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 críticos, como un reproductor de video en la mitad inferior de la página.

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

Establece conexiones tempranas con los orígenes necesarios

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

Hay dos tipos de <link>, preconnect y dns-prefetch, que pueden ayudarte en este caso:

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 se inicie lo antes posible. Cuando el navegador solicita un recurso del origen preconectado, la descarga comienza de inmediato.

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

dns-prefetch

<link rel="dns-prefetch> controla un pequeño subconjunto 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 orígenes seguros, negociaciones 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 críticas. Para dominios de terceros menos importantes, usa <link rel=dns-prefetch>.

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

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

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

Recursos de terceros de carga diferida

Los recursos incorporados de terceros pueden ralentizar considerablemente la carga de la página si se estructuran de manera deficiente. Si no son fundamentales o están en la mitad inferior de la página (es decir, si los usuarios tienen que desplazarse para verlas), 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.

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 de la mitad inferior de la página aparece sin saturación porque aún no se cargó.
Carga de forma diferida contenido en la mitad inferior de la página.

Un enfoque eficaz es realizar una carga diferida de contenido de terceros después de que se carga el contenido de la página principal. Los anuncios son una buena opción para este enfoque.

Los anuncios son una fuente importante de ingresos para muchos sitios, pero los usuarios vienen por el contenido. Mediante la carga diferida de anuncios y la publicación del contenido principal más rápido, puedes aumentar el porcentaje de visibilidad general de un anuncio. Por ejemplo, MediaVine cambió a los anuncios de 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 que el contenido de terceros se cargue solo cuando los usuarios se desplacen por primera vez a esa sección de la página.

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

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

Optimice la forma en que publica secuencias de comandos de terceros

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

Hosting CDN de terceros

Es común que los proveedores externos proporcionen URLs para los archivos JavaScript que alojan, generalmente, en una red de distribución de contenidos (CDN). Los beneficios de este enfoque son que puedes comenzar rápidamente (solo copia y pega la URL) y no hay sobrecarga de mantenimiento. El proveedor externo controla la configuración del servidor y 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 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 el almacenamiento en caché. Depender de la estrategia de almacenamiento en caché de otra persona podría hacer que las secuencias de comandos se vuelvan a recuperar innecesariamente de la red con demasiada frecuencia.

Aloja por cuenta propia las secuencias de comandos de terceros

El alojamiento autónomo de secuencias de comandos de terceros es una opción que te da más control sobre el proceso de carga de una secuencia de comandos. Con el hosting propio, puedes hacer lo siguiente:

Por ejemplo, Casper logró reducir 1.7 segundos en los tiempos de carga mediante el alojamiento propio de una secuencia de comandos de pruebas A/B.

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

Usa service workers para almacenar en caché secuencias de comandos de servidores de terceros

Puedes usar service worker para almacenar en caché secuencias de comandos de servidores de terceros como alternativa al hosting propio. Esto te brinda un mayor control sobre el almacenamiento en caché y, al mismo tiempo, conserva 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 tempranas y ayudar a mitigar los costos de red.