Kodokon kodokon.com

Rendimiento de carga: defer, async, preload y prefetch

Ordena la ejecución de tus scripts con defer y async, y luego dirige la red con preload, preconnect y prefetch.

10 min · 3 preguntas

Abrir esta lección en Kodokon

Un <script src> clásico bloquea el análisis del HTML: el navegador se detiene, descarga, ejecuta y luego reanuda. Dos atributos cambian las reglas del juego. defer descarga en paralelo con el análisis y ejecuta los scripts en el orden del documento, justo antes de DOMContentLoaded: es la elección por defecto para tu código de aplicación, que puede depender del DOM y de otros scripts. async también descarga en paralelo, pero ejecuta en cuanto llega el archivo, sin orden garantizado: resérvalo para scripts autónomos como la analítica, que no dependen de nada.

HTML
<script src="/js/analytics.js" async></script>
<script src="/js/vendor.js" defer></script>
<script src="/js/app.js" defer></script>
vendor.js se ejecutará siempre antes que app.js

El navegador solo descubre algunos recursos críticos muy tarde: una fuente referenciada dentro de un archivo CSS, una imagen cargada en JavaScript. <link rel="preload"> corrige ese descubrimiento tardío al declarar el recurso directamente en el <head>, con el atributo as obligatorio para que el navegador aplique la prioridad y la caché correctas. Caso de manual: las webfonts, que de otro modo solo se solicitan después de haber descargado y analizado el CSS.

HTML
<link rel="preload" as="font" type="font/woff2"
      href="/fonts/inter-var.woff2" crossorigin>
<link rel="preload" as="image"
      href="/img/hero-1600.jpg" fetchpriority="high">
Descubrimiento temprano de una fuente y de la imagen LCP

Última familia: las pistas de red de baja prioridad. <link rel="preconnect"> establece la conexión completa por adelantado (DNS, TCP, TLS) hacia un origen de terceros que sin duda vas a usar: hasta 300 ms ahorrados en la primera petición. dns-prefetch es su primo ligero (solo resolución DNS), útil como respaldo para orígenes menos seguros. Y prefetch descarga, durante el tiempo de inactividad, un recurso destinado a la próxima navegación: la página de pago desde el carrito, por ejemplo. El compromiso está claro: preload sirve a la página actual, prefetch apuesta por la siguiente.

HTML
<link rel="preconnect"
      href="https://api.example.com">
<link rel="dns-prefetch"
      href="https://cdn.example.com">
<link rel="prefetch" href="/checkout.html">
Conexiones tempranas y una apuesta por la próxima navegación

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿Qué garantía ofrece defer que async no ofrece?
    • La descarga en paralelo con el análisis del HTML
    • La ejecución en el orden del documento, antes de DOMContentLoaded
    • La ejecución antes de cualquier renderizado de la página
  2. ¿Por qué es necesario crossorigin en un preload de fuente del mismo origen?
    • Las fuentes se solicitan siempre en modo CORS; sin él, el archivo se descarga dos veces
    • Es un requisito de seguridad del formato WOFF2
    • Sin él, el preload lo bloquea la CSP por defecto
  3. ¿Cuál es el uso correcto de rel="prefetch"?
    • Acelerar un recurso crítico de la página actual
    • Descargar, a baja prioridad, un recurso probable para la próxima navegación
    • Forzar un archivo a un almacenamiento en caché permanente