PRIVACIDAD

Tus preferencias.

Rechazar no limita el acceso a la web. Cerrar sin guardar conserva tu decisión anterior.

Técnicas · siempre activas

Guardamos únicamente tu elección durante un máximo de 12 meses en este navegador.

Consultar proveedores, duración y transferencias

WPO

Preload y preconnect: precarga de recursos sin errores

Cuándo usar preload, preconnect, dns-prefetch, Speculation Rules y Early Hints, con pruebas de los errores más caros y lo que hay en mi web.

¿Quieres aplicarlo a tu web?Hablemos
ResumenQué son los resource hints y qué no hacen
Puntos clave
  • preload adelanta un recurso que el navegador descubriría tarde; no mejora lo que ya está en el HTML. Úsalo con fuentes, la imagen LCP puesta por CSS o JavaScript y poco más.
  • Las fuentes precargadas necesitan crossorigin aunque sean de tu dominio. Sin él, el preload no se reutiliza y la fuente puede descargarse dos veces.
  • preconnect solo vale para orígenes externos que vas a usar enseguida; el navegador cierra la conexión si no se usa en 10 segundos. Para el resto, dns-prefetch.
  • prefetch, Speculation Rules y 103 Early Hints sirven a casos distintos: la siguiente navegación y los servidores que tardan en responder.
  • Google ha dicho que Googlebot no necesita estas pistas. Su efecto en SEO pasa por la experiencia del usuario y el LCP, no por el rastreo.
  • Se comprueba en la consola de DevTools (avisos de preload sin usar), en la pestaña Network (prioridad y orden) y en Lighthouse.

Lo habitual es encontrar webs con una docena de <link rel="preload"> copiados de un tutorial: tres fuentes que ya estaban en el CSS, el logo, un script de analítica y una imagen que ni siquiera se usa en esa plantilla. El resultado es tráfico de red que compite con lo que sí importa y un aviso en la consola que nadie lee.

Separo cada pista (preload, preconnect, dns-prefetch, prefetch, modulepreload, Speculation Rules y 103 Early Hints), cuándo sirve cada una, los errores más caros con una prueba propia y qué hay de todo esto en cristofercruz.net, medido con Playwright.

Cinco tarjetas en fila: preload, preconnect, dns-prefetch, prefetch y Speculation Rules, cada una con su función en una frase.
Las cinco pistas más usadas y el trabajo de cada una. Las tres primeras ayudan a la carga actual; las dos últimas, a la siguiente navegación.

Qué son los resource hints y qué no hacen

Un resource hint es una indicación que le das al navegador sobre un recurso o un origen antes de que él mismo lo descubra. Se escribe como <link rel="..."> en el <head> o como cabecera HTTP Link. La guía de web.dev sobre el tema deja una regla que conviene tener presente: las directivas preload deben limitarse a los recursos críticos que se descubren tarde.

La distinción importante es entre lo que es una orden y lo que es una sugerencia. Según web.dev, preload es una descarga obligatoria, no una pista; preconnect, en cambio, puede ignorarse o aplicarse a medias, porque mantener una conexión abierta cuesta recursos. Y ninguna de estas pistas cambia el contenido de tu página: solo cambian el momento en que el navegador empieza a trabajar.

PistaQué adelantaPara qué navegaciónCoste si te equivocas
preloadDescarga de un recurso concretoLa actualAncho de banda y prioridad robados a otros recursos
modulepreloadDescarga y compilación de un módulo ESLa actualIgual que preload
preconnectDNS, TCP y TLS con otro origenLa actualConexiones abiertas que no se usan
dns-prefetchSolo la resolución DNSLa actual o enlaces probablesMínimo
prefetchDescarga con prioridad bajaLa siguienteDatos gastados si el usuario no navega
Speculation RulesPrefetch o prerender de una páginaLa siguienteDatos, CPU y analítica contaminada
103 Early HintsPreload y preconnect antes del 200La actualTrabajo inútil si el recurso cambia de URL

Preload: adelantar lo que se descubre tarde

El navegador lee el HTML a medida que llega y lanza las descargas de lo que va encontrando. Una imagen dentro de una etiqueta img se descubre pronto. Una fuente declarada en un @font-face no se pide hasta que el navegador ha descargado el CSS, ha calculado qué elementos la usan y sabe que la necesita. Una imagen LCP puesta como background-image o insertada por JavaScript espera todavía más. Ese tiempo muerto es el que preload recorta.

La guía de optimización del LCP de web.dev lo plantea así: el recurso LCP tiene que poder descubrirse en el HTML inicial; si solo aparece en un CSS o en un JavaScript externo, hay que precargarlo con prioridad alta. Cuando ya está en el HTML, el preload aporta poco, porque el escáner del navegador lo habría encontrado igual.

Dos columnas: casos en que el preload sí aporta (fuentes del CSS, imagen LCP por CSS o JavaScript, imagen responsive, módulos importados) y casos en que no (imagen ya en el HTML, contenido bajo el scroll, recursos dudosos, más de dos o tres a la vez).
Preload sirve para adelantar lo que llega tarde. Lo que ya está en el HTML, o no se usa pronto, no lo necesita.

Fuentes

Es el caso más claro. Una fuente web no se descarga hasta que el texto que la usa está en el árbol de render, y eso retrasa el pintado del texto o provoca un cambio de fuente visible. Precargar las dos o tres variantes que se ven en la primera pantalla evita el salto.

<link rel="preload" href="/assets/fonts/nunito-400.woff2"
      as="font" type="font/woff2" crossorigin>

El crossorigin no es opcional. MDN lo dice así: el precargado de font y fetch exige el atributo, y debe coincidir con el modo CORS y de credenciales del recurso aunque la petición no sea de otro origen. Las fuentes se piden en modo CORS anónimo; un preload sin crossorigin usa otro modo y el navegador no lo reutiliza cuando el CSS pide la fuente. En la sección de errores muestro la prueba.

Imagen LCP

Si la imagen principal va en una etiqueta img del HTML, lo que la acelera es no ponerle loading="lazy" y darle fetchpriority="high"; eso tiene su propio artículo sobre fetchpriority en SEO y no lo repito aquí. El preload entra cuando la imagen no se puede descubrir en el HTML (fondo CSS, carga por JavaScript) o cuando quieres que se pida antes que el CSS. Si es responsive, usa imagesrcset e imagesizes para que el navegador aplique la misma selección que con srcset; la parte de formatos y srcset está en la guía de optimización de imágenes.

<link rel="preload" as="image" type="image/webp"
      href="/img/hero-800.webp"
      imagesrcset="/img/hero-480.webp 480w, /img/hero-800.webp 800w"
      imagesizes="(max-width: 1180px) 100vw, 40vw"
      fetchpriority="high">

Una advertencia que recoge web.dev: preload no cambia la prioridad por sí solo. "Preload lets the browser discover a resource early, but it still fetches the resource with the default priority", así que una imagen precargada sin fetchpriority sigue pidiéndose con prioridad baja. Por eso los dos atributos se complementan.

Hojas de estilo y scripts

Para CSS y JavaScript críticos que se descubren tarde (un @import, un script cargado por otro script), as="style" y as="script" con su href. Aquí el fallo típico es omitir as: web.dev avisa de que equivale a una petición XHR y puede hacer que algunos recursos, como los scripts, se descarguen dos veces. Si lo que quieres es pintar antes, la solución suele estar más arriba: ver qué CSS bloquea el render y cuánto pesa, como cuento en la guía de CSS para SEO.

Los atributos que importan

Tres filas con la combinación de atributos de un preload: fuente con as font, type font/woff2 y crossorigin; imagen LCP con as image, imagesrcset, imagesizes y fetchpriority high; hoja o script con as style o script.
La combinación de atributos cambia según el tipo de recurso. El as y el crossorigin son los que más se olvidan.
AtributoPara qué sirveQué pasa si falta o está mal
asFija la prioridad según el tipo, envía las cabeceras correctas y permite saber si ya está en caché. Valores en MDN: fetch, font, image, script, style, trackSe trata como XHR; posible doble descarga
typeTipo MIME; el navegador lo usa para decidir si precargaSi no lo soporta, ignora el preload
crossoriginModo CORS y credenciales de la peticiónFuentes: el preload no se reutiliza
imagesrcset e imagesizesPreload de imagen responsiveDescarga la versión equivocada
fetchprioritySube o baja la prioridad de la descargaPrioridad por defecto del tipo de recurso

Regla para decidir en dos preguntas: ¿el navegador tardaría en descubrir este recurso? ¿Lo voy a usar en los primeros segundos? Si las dos respuestas no son sí, no lo precargues.

Preconnect y dns-prefetch: conexiones con otros orígenes

Abrir una conexión con un origen nuevo exige resolver el DNS, abrir TCP y negociar TLS antes de pedir el primer byte. preconnect hace ese trabajo por adelantado; dns-prefetch hace solo el primer paso. web.dev cifra la búsqueda DNS entre 20 y 120 ms, lo que da una idea de lo que se ahorra con el segundo y de por qué el primero ahorra más.

Tres filas con los pasos DNS, TCP, TLS y petición: preconnect adelanta los tres primeros, dns-prefetch solo el DNS y sin pista no se adelanta ninguno.
Preconnect adelanta DNS, TCP y TLS; dns-prefetch solo el DNS. La petición siempre espera a que la necesite la página.
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="dns-prefetch" href="https://fonts.gstatic.com">

Tres reglas que salen de la documentación de web.dev:

  • Solo tiene sentido con orígenes distintos al tuyo. Con el propio dominio la conexión ya está abierta.
  • Si el recurso se carga en modo anónimo (las fuentes), el preconnect necesita crossorigin; sin él, el navegador solo hace la búsqueda DNS.
  • El navegador cierra la conexión si no se usa en 10 segundos, y demasiados preconnect compiten por ancho de banda. Reserva el preconnect para los orígenes más críticos y usa dns-prefetch para el resto.

Para el respaldo de navegadores antiguos, web.dev recomienda dos etiquetas separadas, una por cada valor, en lugar de rel="dns-prefetch preconnect" en una sola: en Safari esa combinación hace que el preconnect se cancele. Si tu CDN sirve los estáticos desde otro dominio, es el candidato natural a preconnect; cómo elegir y configurar el CDN está en el artículo sobre CDN y SEO.

Prefetch, prerender y Speculation Rules: la página siguiente

prefetch descarga un recurso con prioridad baja para una navegación futura y lo guarda en la caché HTTP. MDN lo marca como disponibilidad limitada y avisa de que, por la partición de caché, no sirve para recursos de otros sitios. También lo bloquean directivas Cache-Control como no-store, algo que enlaza con lo que cuento en la guía de caché para SEO.

Para documentos completos, MDN recomienda la Speculation Rules API donde esté soportada. Las reglas van en un bloque JSON y permiten dos acciones: prefetch (solo el documento) y prerender (la página entera, renderizada en segundo plano, lista para activarse al instante).

<script type="speculationrules">
{
  "prerender": [{
    "where": { "href_matches": "/blog/*" },
    "eagerness": "moderate"
  }]
}
</script>
Dos tarjetas comparan prefetch, que solo descarga el documento, con prerender, que lo renderiza y ejecuta su JavaScript; debajo, los cuatro niveles de eagerness: conservative, moderate, eager e immediate.
Prefetch descarga; prerender además renderiza y ejecuta. El nivel de eagerness decide cuándo se dispara.

Lo que dice la documentación de Chrome Developers sobre el estado actual, que conviene releer antes de implementarlo porque cambia con las versiones:

  • El prerender funciona en Chrome y Edge desde la versión 109; Firefox no lo soporta y Safari lo tiene tras un flag. Es una mejora progresiva: en los navegadores que no lo entienden, no pasa nada.
  • El eagerness admite conservative (al pulsar), moderate (en escritorio, tras 200 ms de hover), eager e immediate. Por defecto, las reglas de lista usan immediate y las de documento, conservative.
  • La analítica puede contar páginas prerenderizadas que el usuario nunca ve; con herramientas que no lo gestionen, usa document.prerendering y el evento prerenderingchange.

Lo que no he encontrado documentado es cómo trata Googlebot estas reglas. No lo afirmo en un sentido ni en otro. Para el SEO, la ventaja es indirecta: una navegación que se siente instantánea mejora la experiencia, y el riesgo es de medición, no de indexación.

modulepreload: módulos ES

Con módulos ES, preload as="script" solo descarga el archivo. Según MDN, modulepreload descarga, analiza y compila el módulo y lo deja en el module map del documento. El navegador puede buscar las dependencias por su cuenta, pero no está obligado: para asegurarlo, declara cada una con su propio link.

<link rel="modulepreload" href="/js/main.js">
<link rel="modulepreload" href="/js/utils.js">
<script type="module" src="/js/main.js"></script>

Es para aplicaciones con dependencias en cascada; en una web de contenidos con un par de scripts defer no aporta nada. Que el contenido llegue al HTML se decide antes, en la guía de JavaScript SEO.

103 Early Hints: pistas antes de la respuesta

Mientras el servidor genera el HTML (consultas a base de datos, renderizado en servidor), el navegador está parado. 103 Early Hints es una respuesta HTTP preliminar que el servidor puede enviar antes del 200 con cabeceras Link, para que el navegador empiece a descargar lo crítico durante ese tiempo.

Línea de tiempo con dos carriles: el servidor envía un 103 con Link preload, luego genera el HTML y envía el 200; el navegador empieza a descargar tras el 103 y recibe el HTML después.
El 103 llega antes que el 200. Solo compensa si el servidor tarda en responder.
HTTP/2 103
link: </assets/app.css>; rel=preload; as=style
link: <https://cdn.example.com>; rel=preconnect

HTTP/2 200
content-type: text/html

Según la documentación de Chrome Developers:

  • Se recomienda enviarlo solo sobre HTTP/2 o HTTP/3, y solo a peticiones de navegación (sec-fetch-mode: navigate), porque algunos clientes antiguos o bots pueden tener problemas con las respuestas informativas.
  • Soporte de preconnect en Early Hints: Chrome 103, Edge 103, Firefox 120 y Safari 17. De preload: Chrome 103, Edge 103 y Firefox 123; Safari no.
  • Chrome no admite prefetch en Early Hints.
  • Los recursos tienen que ser cacheables o se descargan dos veces.
  • Si el servidor puede contestar con el 200 al instante, la propia documentación recomienda usar preload o preconnect normales.

La página cita a Cloudflare, Fastly y Akamai como plataformas con soporte. No he probado Early Hints para este artículo y prefiero decirlo que enseñar un resultado que no he visto.

Qué hace Googlebot con las resource hints

El 26 de febrero de 2026, Search Engine Journal recogió lo que Gary Illyes y Martin Splitt dijeron en el podcast Search Off the Record: estas pistas resuelven problemas de latencia del navegador del usuario que la infraestructura de Google no tiene. Del DNS, Illyes comentó que el dns-prefetch es muy útil si tienes una conexión mala, pero que Google llega muy rápido a los servidores DNS. La lista de las cuatro pistas ignoradas (dns-prefetch, preload, prefetch, preconnect) es el resumen del medio, no una cita literal.

La consecuencia práctica: no son una palanca de rastreo ni de indexación. Su efecto en SEO pasa por la experiencia del usuario: mejor LCP en datos de campo, menos salto de fuente, navegaciones más rápidas.

Relación con el LCP

Web.dev descompone el LCP en cuatro partes: TTFB, retraso de carga del recurso, duración de la carga y retraso de renderizado, con unas proporciones orientativas de 40 %, menos de 10 %, 40 % y menos de 10 %. Las pistas atacan sobre todo la segunda: el tiempo entre que llega el HTML y empieza a descargarse el recurso LCP. Si tu LCP lo domina el TTFB o el peso de la imagen, precargar no mueve nada. Los umbrales y las causas están en la guía de Core Web Vitals; la comprobación es empírica: mides el desglose, añades la pista y vuelves a medir.

Errores frecuentes, con una prueba propia

Seis tarjetas con errores de preload: fuente sin crossorigin, preload que no se usa, as ausente o erróneo, type no soportado, demasiados preloads y preconnect a todo.
Seis errores habituales. Casi todos dejan huella en la consola de DevTools.

Monté una página de prueba con Chromium 141 (Playwright) y un servidor mínimo que registra cada petición. Tenía una fuente con preload correcto, otra con preload sin crossorigin, una tercera fuente precargada sin ser usada y una imagen precargada con as="image" que tampoco se usaba. Esto es lo que vi en la consola:

A preload for 'http://127.0.0.1:8731/g.woff2' is found, but is not used because
the request credentials mode does not match. Consider taking a look at
crossorigin attribute.

The resource http://127.0.0.1:8731/img.webp was preloaded using link preload
but not used within a few seconds from the window's load event. Please make
sure it has an appropriate `as` value and it is preloaded intentionally.

El primer aviso es el de la fuente sin crossorigin; el segundo, el de cualquier recurso precargado que no se usa (lo mostró también para las dos fuentes sobrantes). Después hice la prueba de la doble descarga, con dos configuraciones del servidor:

Cabecera de caché del servidorPeticiones al servidor de la fuente sin crossoriginPeticiones de la fuente correcta
Cache-Control: no-store21
Cache-Control: max-age=36001 (la segunda salió de la caché HTTP)1

Es decir, con una respuesta cacheable, la doble descarga de una fuente sin crossorigin no llegó al servidor en mi prueba, aunque el preload seguía siendo inútil y el aviso aparecía igual. Con no-store sí hubo dos peticiones. Es una prueba de laboratorio con un solo navegador y archivos locales, no una regla general: el resultado depende de las cabeceras de caché del recurso, y la documentación de Chrome sobre Early Hints dice lo mismo para los recursos no cacheables.

Otros fallos que veo en auditorías:

  • Preload de lo que no se usa en esa plantilla. Un tema que precarga la fuente del carrusel en todas las páginas, haya carrusel o no. DebugBear lo resume bien: suele ser un preload (prioridad alta) donde se quería un prefetch (prioridad baja), o un recurso retirado de la página cuya etiqueta se quedó.
  • fetchpriority="high" en todo lo precargado. web.dev avisa de que poner prioridad alta en más de una o dos imágenes deja de servir para algo.
  • Precargar la imagen que además lleva loading="lazy". Se contradicen; el criterio sobre qué cargar de forma diferida está en la guía de carga diferida.

Cómo lo tengo en mi web

Esto es lo que hay en cristofercruz.net, leído en includes/header.php y medido en local con Playwright (Chromium 141) en la home y en un artículo del blog. Los tiempos en localhost no significan nada, así que solo cuento qué se pide, en qué orden y con qué prioridad.

Cuatro filas: sí hay tres fuentes WOFF2 con preload y crossorigin, sí hay preload del retrato de la home con imagesrcset; no hay preconnect, dns-prefetch, prefetch ni Speculation Rules; no hay modulepreload, cabeceras Link ni Early Hints.
Dos cosas que sí uso y dos que no. La portada del artículo no se precarga.
PistaEstado en mi web
preload de fuentesSí: DM Serif Display 400, Nunito 400 y Nunito 700, con as="font", type="font/woff2" y crossorigin, en todas las páginas con el diseño actual
preload de imagenSolo en la home: el retrato principal, con imagesrcset (480 y 800 px), imagesizes y fetchpriority="high"
preconnect y dns-prefetchNo. No hay ninguna petición a otro origen en mis páginas
prefetch y Speculation RulesNo
modulepreloadNo: los scripts son clásicos con defer
Cabeceras Link y 103 Early HintsNo desde mi código ni mi .htaccess. Si el CDN que haya delante los añade, no lo he verificado

Lo que medí:

  • Blog, escritorio (1366 px). Orden de peticiones: el documento, las tres fuentes precargadas (prioridad High), el script del consentimiento de cookies, el logo, el avatar, la portada del artículo (prioridad High, por su fetchpriority="high") y los otros dos scripts. Tras ellos llegan Nunito 600 y la cursiva de DM Serif, que no están precargadas, con prioridad VeryHigh porque las pide el layout. El elemento LCP fue la portada.
  • Blog, móvil (390 px). La portada no se descarga (en pantallas de menos de 900 px el picture sirve un GIF de un píxel) y el elemento LCP fue el h1, texto. Ahí las fuentes precargadas sí pesan en el LCP.
  • Home. Las tres fuentes y el retrato son las primeras peticiones tras el documento, ambas con prioridad High.
  • Origen de las peticiones. En todas las pruebas, cero peticiones a otros orígenes. Hoy no hay ningún proveedor de analítica activo en la configuración del sitio, así que no hay un tercero que justifique un preconnect.

Hay dos huecos que he visto al medir. La portada del artículo no se precarga: no hace falta, porque va en el HTML y lleva fetchpriority="high", pero el navegador no la pide hasta después de dos scripts y un par de imágenes. Y dos variantes de fuente (Nunito 600 y la cursiva de DM Serif) se descubren tarde. Si alguna de las dos se ve en la primera pantalla, es candidata a preload; no he medido si cambia el LCP o el CLS, así que de momento no lo toco.

Cómo auditarlo

El orden que sigo en una auditoría, de menos a más esfuerzo:

  1. Consola de DevTools. Recarga la página y busca los avisos de preload: el de not used within a few seconds y el de credentials mode does not match. Cada uno es un error a corregir.
  2. Pestaña Network, columna Priority. Actívala con clic derecho en la cabecera de la tabla. Comprueba que la imagen LCP y las fuentes críticas salen pronto y con prioridad alta, y que no hay dos filas para el mismo archivo.
  3. Cascada y subpartes del LCP. En Performance o en PageSpeed Insights, mira el retraso de carga del recurso LCP. Si es alto y el recurso no está en el HTML, es el candidato a preload.
  4. Código fuente. Lista los <link rel="preload|preconnect|dns-prefetch|prefetch"> con view-source y comprueba que cada uno tiene un uso real en esa plantilla.
  5. Cabeceras. curl -I y busca link: por si hay pistas enviadas desde el servidor o el CDN.

Cambia una cosa cada vez y mide antes y después con el mismo perfil de red; con tres preloads a la vez no sabrás cuál ayuda.

Auditoría SEO

Ver auditoría SEO

Preguntas frecuentes

¿Preload mejora el posicionamiento?

No de forma directa. Google ha dicho que Googlebot ignora estas pistas. Lo que puede mejorar es el LCP y la experiencia de los usuarios, y eso sí está dentro de las señales de experiencia de página.

¿Cuántos preloads puedo poner?

No hay un número mágico documentado. La guía de web.dev pide limitarlos a los recursos críticos que se descubren tarde, y como preload tiene prioridad alta, abusar de él puede saturar el ancho de banda. En la práctica, dos o tres fuentes y una imagen es lo máximo que suelo ver justificado.

¿Por qué mis fuentes se descargan dos veces?

Lo más probable es que el preload no lleve crossorigin. Las fuentes se piden en modo CORS anónimo, y un preload sin ese atributo usa otro modo, así que no se reutiliza. Si además el recurso no es cacheable, el navegador lo pide dos veces; en mi prueba, con max-age la segunda salió de la caché.

¿Preconnect o dns-prefetch?

preconnect para los pocos orígenes críticos que vas a usar en los primeros segundos; dns-prefetch para el resto y como alternativa más barata. Recuerda poner crossorigin en el preconnect de recursos anónimos como las fuentes.

¿Hace falta preload si ya uso fetchpriority="high"?

Depende de dónde esté la imagen. Si va en una etiqueta img del HTML, fetchpriority="high" suele bastar. Si la pone el CSS o JavaScript, necesitas el preload para que se descubra pronto, y es buena idea añadirle también fetchpriority="high".

Referencias

  1. Preload critical assets to improve loading speed web.dev · Google
  2. Establish network connections early to improve perceived page speed web.dev · Google
  3. Optimize Largest Contentful Paint web.dev · Google
  4. Early Hints Chrome for Developers
  5. Prerender pages in Chrome for instant page navigations Chrome for Developers
  6. Google explains why its crawler ignores your resource hints Search Engine Journal
  7. Common rel=preload problems DebugBear

Sigue leyendo

WPO

· 14 min

fetchpriority: qué hace y cómo usarlo para el LCP

Qué es el atributo fetchpriority, dónde funciona y dónde no, cómo se combina con preload y lazy loading, con pruebas propias en Chrome y en mi web.

Leer el artículo: fetchpriority: qué hace y cómo usarlo para el LCP
Multimedia

· 14 min

Optimización de imágenes SEO: formatos, carga y tamaño

Qué documenta Google sobre imágenes, cómo elegir formato, tamaño y carga sin romper el LCP ni el CLS, y qué hago yo en mi propia web.

Leer el artículo: Optimización de imágenes SEO: formatos, carga y tamaño

Tu próximo paso empieza con una conversación.

Cuéntame qué necesitas conseguir con tu web.

Hablemos de tu proyecto