Guía de priorización de recursos para Core Web Vitals
Controla qué recursos cargan primero y cuáles esperan.
Guía de Core Web Vitals para la priorización de recursos
El motor de priorización por defecto del navegador funciona con heurísticas: suposiciones imperfectas basadas en los tipos de archivo y su ubicación en el documento. Los recursos se ponen en cola en el momento en que los descubre el escáner de precarga o el analizador del DOM.
Última revisión por Arjen Karel en febrero de 2026

Esto se convierte en un problema si consideras que el ancho de banda de la red y la CPU no son recursos ilimitados. Por ejemplo: cada byte transferido para un script de seguimiento de baja prioridad, al descargarse simultáneamente, compite directamente con los bytes que necesita tu Largest Contentful Paint (LCP).
Esto no es culpa del navegador. En el HTML de nuestro ejemplo, el navegador no tenía forma de saber que había priorizado los recursos incorrectos. Esto retrasó el renderizado crítico.
Tú sabes qué es importante. Controlas esta programación mediante dos mecanismos: Priorización (potenciar las señales críticas) y Despriorización (programar los recursos no críticos para cuando sean menos intrusivos).
Table of Contents!
Limitaciones de las heurísticas del navegador
Los navegadores asignan la prioridad basándose en una puntuación de "prioridad calculada". Esta puntuación deriva del tipo de recurso (CSS, script, imagen) y su posición en el HTML o el DOM. Aunque suele ser eficaz para documentos sencillos, este sistema falla cuando el escáner de precarga no reconoce los recursos a tiempo o cuando se activa la descarga anticipada de recursos incorrectos.
Niveles de prioridad por defecto de Chrome
Chrome utiliza cinco niveles internos de prioridad: La más alta, Alta, Media, Baja y La más baja. Así los asigna por defecto:
| Recurso | Prioridad por defecto | Con fetchpriority="high" | Con fetchpriority="low" |
|---|---|---|---|
CSS (en el <head>) | La más alta | (ya es la máxima) | Alta |
Script (bloqueante, en el <head>) | La más alta | (ya es la máxima) | Baja |
| Script (async / defer) | Baja | Alta | La más baja |
| Fuente (vía preload) | La más alta | (ya es la máxima) | n/a |
| Fuente (en CSS) | Alta | n/a | n/a |
| Imagen (por defecto) | Baja | Alta | La más baja |
| Imagen (primeras 5 grandes) | Media | Alta | Baja |
| Imagen (en el viewport, tras el layout) | Alta | (ya es Alta) | n/a |
El atributo fetchpriority está soportado en los elementos <img>, <link> y <script>. Tiene un 93% de soporte global en navegadores (Chrome 102+, Firefox 132+, Safari 17.2+, Edge 102+) y es una mejora progresiva: los navegadores que no lo soportan simplemente lo ignoran. Según el Web Almanac de 2025, el 17% de las páginas móviles usan hoy fetchpriority="high", pero solo el 0,3% usa fetchpriority="low". Esto significa que la despriorización es una optimización enormemente infrautilizada.
La limitación del escáner de precarga
Para acelerar el descubrimiento, los navegadores emplean un "escáner de precarga" (preload scanner). Es un analizador ligero que se adelanta al analizador principal de HTML para encontrar las URL de los recursos. Este escáner tiene limitaciones que lo hacen rápido y eficaz: solo analiza HTML. No puede ver el interior de los archivos CSS, no ejecuta JavaScript y no renderiza. Por lo tanto, no puede determinar si los recursos son visibles en el viewport.
Como consecuencia, cualquier recurso referenciado en una hoja de estilos (como una imagen de fondo o una fuente web), inyectado por un script o mediante lazy loading, se ignora hasta que el analizador principal descarga y procesa toda la página web. Esto crea un "retraso en el descubrimiento", donde el navegador no tiene forma de saber que existen recursos críticos.
Contención de recursos
Cuando el navegador descubre recursos, suele intentar descargarlos simultáneamente junto con otras peticiones pendientes. Si una imagen importante para el LCP compite con un script de prioridad media o con imágenes sin importancia (como los iconos de redes sociales en el pie de página), se dividen el ancho de banda disponible. Esta contención prolonga el tiempo de carga de ambos y empuja la métrica del LCP a la zona "Necesita mejora".
Estrategias de priorización manual
Para construir una ruta de renderizado rápida, debes intervenir manualmente. El objetivo es maximizar el ancho de banda para el LCP y minimizarlo para todo lo demás. En los sitios monitorizados por CoreDash, el 82% de los sitios que usan fetchpriority="high" en su imagen del LCP aprueban el LCP, en comparación con el 61% de los sitios que no lo hacen.
1. Corrige el descubrimiento con precarga
Debes exponer manualmente los recursos ocultos al escáner de precarga. Al mover los recursos críticos al <head> del HTML usando rel="preload", obligas al navegador a reconocerlos de inmediato. Esto elimina el retraso en el descubrimiento. Para ver los pasos completos, consulta nuestra guía para precargar la imagen del LCP.
La implementación:
<!-- Expone la fuente al escáner de inmediato -->
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter-bold.woff2" crossorigin>
<!-- Expone la imagen de fondo del LCP de inmediato -->
<link rel="preload" as="image" href="/images/hero-banner.jpg" fetchpriority="high">
Para un descubrimiento aún más temprano, considera los 103 Early Hints. Estos envían señales de precarga al navegador antes de que llegue la respuesta HTML.
2. Sobrescribe las heurísticas del LCP
Los navegadores suelen asignar la prioridad "Baja" o "Media" a las imágenes porque no conocen las dimensiones finales del layout durante la petición inicial. El navegador no puede determinar si una imagen es el LCP hasta que se construye el árbol de renderizado. Para entonces, ya es demasiado tarde.
La implementación:
Fuerza el estado de prioridad "Alta" en el elemento del LCP utilizando fetchpriority="high". Esto ignora las heurísticas internas y coloca la imagen al principio de la cola de descargas. Google Flights mejoró su LCP de 2,6 segundos a 1,9 segundos (una mejora de 0,7 segundos) añadiendo este único atributo.
<!-- Fuerza una petición inmediata de alta prioridad -->
<img src="hero.jpg" alt="Producto principal" fetchpriority="high">
El peor error en este caso es usar lazy loading en la imagen del LCP. Esto desprioriza activamente el elemento más importante de la página.
3. Desprioriza las imágenes sin importancia
Liberar ancho de banda suele ser más efectivo que aumentar la prioridad. Debes retrasar explícitamente los recursos no esenciales. Así despejas la red para los recursos críticos.
La implementación:
- Bajo el pliegue: Usa
loading="lazy"para posponer las imágenes fuera de pantalla hasta que el usuario haga scroll. - Sobre el pliegue, secundario: Usa
fetchpriority="low"para las diapositivas de un carrusel o elementos visuales secundarios que se renderizan inicialmente pero son menos importantes que el LCP. - Sobre el pliegue, sin importancia visual: Ignora el escáner de precarga usando
loading="lazy"y asigna una prioridad de ancho de banda baja. Esto es útil para imágenes pequeñas, como banderas o iconos, que nunca llaman la atención durante el primer renderizado pero pueden provocar muchas peticiones iniciales en la red.
<!-- Imagen del LCP: la prioridad más alta -->
<img src="slide-1.jpg" fetchpriority="high">
<!-- Imagen secundaria del carrusel: petición inmediata, bajo uso de ancho de banda -->
<img src="slide-2.jpg" fetchpriority="low">
<!-- Banderas de traducción: aunque estén en el viewport, ocúltalas al escáner de precarga -->
<img src="dutch-flag.jpg" loading="lazy" fetchpriority="low">
<!-- Imagen fuera de pantalla: petición pospuesta -->
<img src="footer-promo.jpg" loading="lazy"> 4. Controla la ejecución de scripts
El JavaScript bloquea el analizador del DOM. Si usas etiquetas <script> estándar, el navegador detiene el análisis del HTML para descargar y ejecutar el archivo. La ejecución incontrolada de scripts también perjudica directamente el Interaction to Next Paint (INP) al bloquear el main thread.
La implementación:
- defer: Úsalo para la lógica de la aplicación. Se descarga en paralelo (prioridad Baja) y se ejecuta solo después de que el HTML se haya analizado por completo. Esto conserva el orden de dependencias.
- async: Úsalo para scripts independientes de terceros (como las analíticas). Se descarga en paralelo y se ejecuta inmediatamente al terminar, ignorando el orden.
- async + fetchpriority="high": Úsalo para scripts asíncronos críticos (como los test A/B) que necesitan una descarga rápida sin bloquear el análisis. Esto eleva la prioridad de descarga de Baja a Alta y mantiene la ejecución no bloqueante.
- Inyectar: Ignora el escáner de precarga para que no compita por el ancho de banda temprano. Los scripts inyectados se tratan como asíncronos.
- Programar + inyectar: Inyecta scripts más adelante, por ejemplo, cuando se haya disparado el evento load.
<!-- Lógica de la aplicación: no bloqueante, conserva el orden de ejecución -->
<script src="app.js" defer></script>
<!-- Consentimiento de terceros: no bloqueante, ejecución independiente -->
<script src="consent.js" async></script>
<!-- Async crítico: descarga rápida, ejecución no bloqueante -->
<script src="ab-test.js" async fetchpriority="high"></script>
<script>
/* Ejemplo de inyección de analíticas */
const script = document.createElement('script');
script.src = 'analytics.js';
script.async = true;
document.head.appendChild(script);
/* Ejemplo de programar + inyectar para un chat */
window.addEventListener('load', () => {
const chatScript = document.createElement('script');
chatScript.src = 'chat-widget.js';
document.head.appendChild(chatScript);
});
</script>
Para un desglose completo de todas las técnicas disponibles, consulta 16 métodos para aplazar el JavaScript y async vs defer en JavaScript. Para orientarte sobre cómo categorizar los scripts según su criticidad, lee los niveles de prioridad en JavaScript.
5. Desbloquea el renderizado de CSS
El CSS es render blocking por diseño: el navegador no sabe qué aspecto tiene la página sin el CSS. Por eso descarga y analiza primero las hojas de estilo.
Estrategias de optimización:
- Evita el @import: Crea cadenas de dependencias secuenciales que devastan el rendimiento.
- Optimiza el tamaño del bundle: Evita archivos CSS de menos de 3 kB (sobrecarga) y de más de 20 kB (bloqueantes). Lo ideal es apuntar a archivos de ~15 kB.
- Carga asíncrona: Carga los estilos fuera de pantalla de forma asíncrona para desbloquear la ruta crítica.
- El compromiso del CSS crítico: Aunque inyectar el CSS crítico en línea mejora la primera visita a la página, omite la caché del navegador. Esto puede retrasar las visitas posteriores.
La implementación:
Elimina el @import por completo. Usa etiquetas <link> para cargar en paralelo. Para el CSS no crítico (como los estilos de impresión), usa el atributo media para desbloquear el main thread. Para saber más sobre la optimización de CSS, consulta cómo eliminar el CSS no utilizado.
<!-- CSS crítico: bloquea el renderizado (correcto) -->
<link rel="stylesheet" href="main.css">
<!-- CSS de impresión: no bloquea hasta que ocurre el evento de impresión -->
<link rel="stylesheet" href="print.css" media="print">
<!-- Patrón asíncrono: se descarga con prioridad baja y se aplica al cargar -->
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'"> 6. Estabiliza el renderizado de fuentes
Las fuentes son recursos pesados y bloqueantes. Una priorización eficaz exige límites estrictos sobre lo que se descarga y un control total sobre su renderizado.
Estrategias de optimización:
- Límites estrictos de precarga: Precarga solo los 1 o 2 archivos de fuentes más importantes (normalmente el texto del LCP). Precargar 5 o más fuentes satura el ancho de banda.
- Autoalojamiento: Autoaloja tus fuentes web en lugar de cargarlas desde un CDN de terceros. Esto elimina la configuración de conexiones adicionales.
- Reduce el payload: Usa fuentes variables (un solo archivo para todos los grosores) y subsetting (elimina los caracteres no utilizados) para minimizar el tamaño del archivo.
- Estrategia de renderizado:
- Usa
swappara un renderizado rápido (evita el texto invisible). Consulta cómo garantizar que el texto siga siendo visible mientras se carga la fuente web. - Usa
optionalpara prevenir el CLS (evita los cambios de layout en redes lentas).
- Usa
La implementación:
<!-- Precarga SOLO el subconjunto crítico (por ejemplo, encabezado y cuerpo) -->
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face {
font-family: 'Inter Variable';
src: url('/fonts/inter-var.woff2') format('woff2-variations');
/* Elige en función de los requisitos de estabilidad: */
font-display: optional; /* Sin cambios de layout, pero la fuente podría quedarse en el fallback */
/* font-display: swap; Visibilidad del texto más rápida, pero con riesgo de cambios de layout */
}
</style> 7. Acelera las conexiones
Antes de que un navegador pueda descargar un recurso de un origen de terceros, necesita realizar una búsqueda DNS, establecer una conexión TCP y negociar el cifrado TLS. Esto lleva tiempo. Puedes eliminar este retraso indicando al navegador que configure las conexiones con antelación.
La implementación:
- preconnect: Úsalo para orígenes críticos de terceros que sepas que el navegador va a necesitar. Realiza el handshake completo (DNS + TCP + TLS) por adelantado.
- dns-prefetch: Úsalo para orígenes menos críticos. Solo realiza la resolución DNS. Es más ligero, pero te ahorra entre 20 y 120 ms.
<!-- Terceros críticos: conexión temprana completa -->
<link rel="preconnect" href="https://cdn.example.com">
<!-- Fallback para navegadores antiguos -->
<link rel="dns-prefetch" href="https://cdn.example.com">
Limita preconnect a entre 2 y 4 orígenes. Cada conexión consume CPU y ancho de banda. Demasiados preconnects compiten con las descargas reales de recursos y pueden perjudicar el rendimiento en lugar de mejorarlo. Según el Web Almanac de 2025, el 22% de las páginas usan preconnect y el 24% usan dns-prefetch. Coloca ambos lo antes posible en el <head>, por delante de cualquier recurso bloqueante.
Tiempo real. No medias de 28 días.
CoreDash segmenta cada métrica por ruta, dispositivo, browser y tipo de conexión.
Echa un vistazo a CoreDash