A mediados de 2022, un sitio de comparación de hosting llegó a mi bandeja de entrada. Catálogo grande — alrededor de 4,000 páginas, estructura de categorías profundamente anidada, enlaces de afiliados esparcidos por todas partes, imágenes hero del tamaño de continentes pequeños. Su Google Search Console era una pesadilla. LCP en 4.2 segundos en móvil. INP (entonces todavía llamado FID) al límite. El cliente ya había gastado £6,000 con una agencia anterior que le había instalado un CDN y lo había dejado ahí.
Ese proyecto es lo que eventualmente moldeó cómo pensamos sobre rendimiento en Seahawk para sitios de alto número de páginas — sitios de directorio, plataformas de listados, propiedades de revisión de hosting como construcciones de estilo HostList. Lo que sigue es el playbook real.Seahawk for high-page-count sites — directory sites, listing platforms, hosting review properties like HostList-style builds. What follows is the actual playbook.
---
Por Qué los Sitios Grandes Rompen el LCP Diferente
Los sitios pequeños tienen problemas simples. Una imagen hero, un tema, un plugin haciendo demasiado. Arregla esas tres cosas y estás por debajo de 2 segundos.
¿Sitios grandes? Otro asunto completamente diferente. El elemento LCP cambia dependiendo de la página en que estés. Un archivo de categoría tiene un candidato LCP diferente al de una página de detalle de producto, que a su vez tiene uno diferente al de la página de inicio. La mayoría de las herramientas de rendimiento reportan una única puntuación. Ese número es una mentira — es un promedio de un conjunto de páginas enormemente variado, y arreglar la página de inicio mientras ignoras las 3.800 páginas de listado debajo de ella es exactamente cómo las agencias se ganan mala reputación.which page you're on. A category archive has a different LCP candidate than a product detail page, which has a different candidate than the homepage. Most performance tools report a single score. That number is a lie — it's an average of a wildly varied set of pages, and fixing the homepage while ignoring the 3,800 listing pages underneath it is exactly how agencies earn bad reputations.
La documentación de Core Web Vitals de Google es clara: los datos de campo — lo que los usuarios reales experimentan, medido en el Chrome User Experience Report — es lo que Google realmente usa para sus señales de ranking. Los datos de laboratorio de PageSpeed Insights son orientativos, no definitivos. He visto sitios obtener 95 en PSI y aún tener LCP Pobre en datos de CrSX. No confundas los dos.Core Web Vitals documentation from Google is clear that field data — what real users experience, measured in Chrome User Experience Report — is what Google actually uses for ranking signals. Lab data from PageSpeed Insights is directional, not definitive. I've seen sites score 95 on PSI and still have Poor LCP in CrSX data. Don't confuse the two.
Los Tres Culpables Reales en Sitios de Listado
En cada sitio grande que he auditado (y he revisado cientos a estas alturas), las fallas de LCP se remontan a tres causas raíz casi siempre:
- Imágenes de hero o tarjeta sin optimizar — a menudo servidas a resolución completa, formato incorrecto, sin sugerencia fetchpriority — often served at full resolution, wrong format, no
fetchpriorityhint - Scripts de terceros que bloquean la renderización — rastreadores de afiliados, redes publicitarias, widgets de comparación que cargan antes de que el navegador pueda pintar algo — affiliate trackers, ad networks, comparison widgets loading before the browser can paint anything
- TTFB inflando el presupuesto de LCP — respuesta lenta del servidor consumiendo 600–900ms antes de que la página siquiera comience a cargar — slow server response eating 600–900ms before the page even starts loading
Ese tercero es el que la gente subestima. Si tu TTFB es 700ms, ya has gastado casi la mitad de tu presupuesto de LCP "Bueno" antes de que el navegador haya renderizado un solo píxel. La elección de hosting y el cachés del lado del servidor no son preocupaciones de DevOps — son preocupaciones de SEO.
---
Comienza con TTFB: Es Primero un Problema de Hosting y Caché
El proyecto tipo HostList que mencioné arriba? Lo primero que hice fue ejecutar WebPageTest desde cinco ubicaciones geográficas diferentes. El TTFB fue consistentemente de 680–820ms. El sitio estaba en un host compartido en Virginia. La mayoría de su tráfico orgánico provenía del Reino Unido y Alemania.WebPageTest from five different geographic locations. TTFB was consistently 680–820ms. The site was on a shared host in Virginia. Most of their organic traffic came from the UK and Germany.
Los moví a un host WordPress gestionado con nodos edge en Londres y Frankfurt. Configuré caché de página completa con tiempos de vida de 12 horas en las páginas de listados (los datos no cambiaban tan frecuentemente de todas formas). El TTFB bajó a 120–180ms en solicitudes repetidas, 280–350ms en fallos de caché de primer acceso. Ese único cambio redujo aproximadamente 500ms del LCP antes de que tocara una sola imagen.
Algunas cosas que siempre verifico del lado del hosting:
- ¿El caché de página completa realmente está funcionando? Verifica el header de respuesta X-Cache. Si dice MISS en cada solicitud, tu capa de caché no está funcionando. Check the
X-Cacheresponse header. If it saysMISSon every single request, your caching layer isn't functioning. - ¿El servidor de origen está geográficamente cerca de tu audiencia principal? Esto suena obvio. Te sorprendería cuán frecuente está mal. This sounds obvious. You'd be surprised how often it's wrong.
- ¿Keep-alive está habilitado? Algunos hosts más baratos aún desactivan conexiones persistentes. Increíble en 2024, pero sucede. Some cheaper hosts still disable persistent connections. Wild in 2024, but it happens.
- ¿HTTP/2 o HTTP/3 están activos? Ejecuta curl -I --http2 https://yourdomain.com y verifica el protocolo en la respuesta. Run
curl -I --http2 https://yourdomain.comand check the protocol in the response.
No toques optimización de imágenes hasta que hayas resuelto el TTFB. Optimizar imágenes en un servidor lento es como pintar una casa que está en llamas.
---
El Problema de Imágenes LCP (Y Por Qué `fetchpriority` Lo Cambia Todo)
Correcto. Imágenes. En un sitio de listados con layouts de grid de tarjetas, el elemento LCP casi siempre es la primera imagen de tarjeta visible en pantalla, o el banner hero. El navegador tiene que descubrirla, descargarla, decodificarla y renderizarla. Cada uno de esos pasos se puede retrasar.
Aquí está lo que realmente hicimos en ese proyecto de HostList, en orden:
- Convertimos todas las imágenes de tarjetas a WebP — usando la conversión en lote de Imagify. El tamaño promedio de archivo se redujo un 58% sin pérdida visible de calidad en los tamaños de miniatura de tarjeta que usábamos (visualización de 280×180px, servida a 2x para retina). — using Imagify's bulk conversion. Average file size dropped 58% without visible quality loss at the card thumbnail sizes we were using (280×180px display, served at 2x for retina).
- Agregamos `fetchpriority="high"` a la primera imagen de tarjeta — Este cambio solo redujo ~200ms del LCP medido en WebPageTest. El navegador deja de tratarla como una imagen lazy normal y la pone en cola inmediatamente en el scanner de precarga. — This one change alone knocked ~200ms off measured LCP in WebPageTest. The browser stops treating it like a regular lazy image and queues it immediately in the preload scanner.
- Removimos `loading="lazy"` de las primeras dos filas de imágenes de tarjeta — La carga lazy es brillante para imágenes debajo del fold. En la primera fila visible, te hace daño activamente. Le dice al navegador que no descargue la imagen hasta que esté cerca del viewport, cuando ya lo está. — Lazy loading is brilliant for below-fold images. On the first visible row, it actively hurts you. It tells the browser to not fetch the image until it's near the viewport — which it already is.
- Agregamos una etiqueta `<link rel="preload">` para la imagen hero en el `<head>` específicamente en la plantilla de la página de inicio. in the
<head>on the homepage template specifically.
Esa secuencia llevó el LCP de la página de inicio de 3.1s a 1.4s en condiciones de lab. Los datos de campo siguieron dentro de aproximadamente 28 días (ese es más o menos el tiempo que tarda los datos de CrUX en reflejar cambios a escala).
Una nota sobre imágenes responsivas
Si estás sirviendo la misma imagen de 1400px de ancho a un dispositivo móvil, estás quemando ancho de banda y agregando tiempo de decodificación. Usa srcset correctamente. Sé que esto suena como una conversación de 2016 pero aún lo veo probablemente en el 40% de los sitios que pasan por Seahawk. La función wp_get_attachment_image() de WordPress genera srcset automáticamente — pero solo si la imagen se subió con suficiente resolución y el tema no la suprimió con add_filter('max_srcset_width', ...).srcset properly. I know this sounds like a 2016 conversation but I still see it on probably 40% of the sites that come through Seahawk. The WordPress wp_get_attachment_image() function generates srcset automatically — but only if the image was uploaded at sufficient resolution and the theme hasn't suppressed it with add_filter('max_srcset_width', ...).
---
Scripts de Bloqueo de Renderizado: El Impuesto del Sitio de Afiliados
Los sitios de comparación de hosting y plataformas de listados viven del ingreso de afiliados. Eso significa scripts de rastreo de terceros. Commission Junction, Impact, Awin, rastreadores de píxeles personalizados — se acumulan. He contado 14 orígenes de scripts de terceros separados en un único sitio de listados. Cada uno es una búsqueda DNS separada, una conexión TCP y un apretón de manos TLS antes de que se reciba un solo byte de ese script.
La solución no es eliminar los scripts. No puedes — los ingresos dependen de ellos. La solución es la secuenciación.
Ningún script de terceros debería nunca bloquear el renderizado inicial del elemento LCP. Punto final.
En la práctica, esto significa:
- Mueve todos los scripts de afiliados/analytics para que carguen después del evento DOMContentLoaded, no en <head>.after the
DOMContentLoadedevent, not in<head>. - Usa atributos async o defer en cada script que controles.
asyncordeferattributes on every script you control. - Para scripts que no controlas (inyectados por gestores de etiquetas), carga Google Tag Manager mismo con defer — sí, esto es seguro para la mayoría de casos de uso de rastreo de afiliados, y la propia documentación de GTM reconoce este enfoque.
defer— yes, this is safe for most affiliate tracking use cases, and GTM's own documentation acknowledges this approach. - Usa un gestor de scripts como Asset CleanUp Pro o la función de retraso de scripts de WP Rocket para diferir terceros no esenciales hasta la interacción del usuario (primer scroll o primer clic).
En la reconstrucción de HostList, diferir scripts de terceros redujo Total Blocking Time de 1,840ms a 290ms. TBT no es un Core Web Vital directamente, pero se correlaciona fuertemente con INP, que sí lo es.is.
---
Carga de fuentes: El asesino silencioso del LCP del que nadie habla
Las fuentes personalizadas causan un modo de fallo específico. El navegador renderiza tu diseño, llega al elemento de texto LCP (a veces el LCP es un encabezado, no una imagen), y luego espera el archivo de fuente antes de pintarlo. Esto se llama Flash of Invisible Text, y retrasa el LCP entre 200ms y más de un segundo dependiendo del tamaño del archivo de fuente y la proximidad del servidor.
Dos cosas lo solucionan:
font-display: swap en tu declaración @font-face — el navegador renderiza en una fuente alternativa inmediatamente e intercambia cuando la fuente personalizada carga. El candidato LCP se pinta a tiempo.in your@font-facedeclaration — the browser renders in a fallback font immediately and swaps when the custom font loads. LCP candidate gets painted on time.- Auto-aloja tus fuentes. Google Fonts añade una solicitud de origen cruzado. El auto-alojamiento con la herramienta google-webfonts-helper te permite servir fuentes desde tu propio dominio, eliminando esa conexión extra.google-webfonts-helper tool lets you serve fonts from your own domain, cutting that extra connection.
Convertí un gran directorio de sitios desde Google Fonts en aproximadamente 45 minutos usando esa herramienta. El LCP mejoró en 180ms. No es transformador por sí solo, pero combinado con todo lo demás, estos márgenes se acumulan.
---
Midiendo lo que realmente importa en el campo
Los datos de CrUX son la verdad de base. Pero solo se actualizan mensualmente y solo para URLs con tráfico suficiente. Para sitios grandes con miles de páginas, necesitas algo más granular.
Utilizo la API de PageSpeed Insights ejecutada en una muestra representativa de URLs — típicamente las 100 páginas principales por tráfico, 50 páginas a nivel de categoría, y 20 páginas "delgadas" de catálogo profundo. Ejecutar esto mensualmente proporciona una distribución de rendimiento adecuada, no una puntuación de un único punto.PageSpeed Insights API scripted across a representative sample of URLs — typically the top 100 pages by traffic, 50 category-level pages, and 20 "thin" deep-catalogue pages. Running this monthly gives a proper performance distribution, not a single-point score.
En Lighthouse CI (que ejecutamos en pipelines CI/CD para clientes que tienen ciclos de desarrollo), verificamos:
- LCP ≤ 2.5s en lab (objetivo conservador, ya que el campo tiende a quedarse rezagado respecto al lab por 10–15%)
- TBT ≤ 300ms
- CLS ≤ 0.1
Pero honestamente — para una compilación tipo HostList donde el objetivo es LCP menor a 1.5s — los objetivos de lab necesitan ser más estrictos. Establecemos LCP ≤ 1.8s en Lighthouse CI para esos proyectos, que típicamente produce 1.3–1.5s en datos de campo una vez que CrUX se pone al día.
---
Juntándolo Todo: El Resultado de HostList
Después de pasar por todo lo anterior — migración de hosting, almacenamiento en caché de página completa, conversión de formato de imagen, fetchpriority en candidatos LCP, eliminación de lazy-load de filas above-fold, aplazamiento de scripts, y auto-hospedaje de fuentes — así es como se veían los números:fetchpriority on LCP candidates, lazy-load removal from above-fold rows, script deferral, and font self-hosting — here's what the numbers looked like:
- TTFB: 780ms → 160ms (mediana, visitantes del Reino Unido): 780ms → 160ms (median, UK visitors)
- LCP (lab, móvil): 4.2s → 1.4s: 4.2s → 1.4s
- LCP (field, CrUX, percentil 75): 3.8s → 1.6s (medido 60 días después de la migración): 3.8s → 1.6s (measured 60 days post-migration)
- TBT: 1,840ms → 290ms: 1,840ms → 290ms
- CLS: ya estaba bien en 0.03, sin cambios: was already fine at 0.03, unchanged
No todos los sitios obtendrán una mejora de 2.8 segundos. Pero casi todos los sitios de listados grandes en los que he trabajado han tenido todos estos problemas simultáneamente, lo que significa que las ganancias se acumulan. Arregla una cosa y obtienes 300ms. Arregla todas y obtienes 2.5 segundos.
---
FAQ
¿Realmente importa tanto el hosting para LCP?
Sí, probablemente más que cualquier otra cosa al principio. Si tu TTFB está por encima de 500ms, ninguna cantidad de optimización de imágenes te llevará a un LCP "Bueno". TTFB es la base sobre la que se asienta todo lo demás. Llévalo por debajo de 200ms primero, luego preocúpate por el resto.
¿Debería usar un CDN en lugar de migrar de host?
Un CDN ayuda con la entrega de activos estáticos y puede reducir el TTFB para HTML de página completa en caché si está configurado correctamente. Pero muchas configuraciones de CDN solo cachean activos, no respuestas HTML completas. Verifica si tu CDN está sirviendo realmente HTML en caché o solo descargando imágenes. Si es lo último, un host de origen mejor hará más por el LCP.
¿`fetchpriority="high"` tiene un soporte generalizado ahora?
A partir de 2024, sí — está soportado en Chrome, Edge y Safari (desde Safari 17.2). El soporte de Firefox llegó en Firefox 132. En navegadores que no lo soportan, se ignora de forma segura. No hay ningún inconveniente en agregarlo a tu elemento LCP de imagen.
¿Cuánto tiempo tarda en reflejarse las mejoras en los datos de CrUX?
Aproximadamente 28 días desde que los usuarios reales comienzan a experimentar la versión más rápida del sitio. CrUX utiliza una ventana móvil de 28 días. Así que si despliega cambios hoy, tu puntuación de datos de campo no los reflejará completamente durante aproximadamente un mes. No entres en pánico si PageSpeed Insights aún muestra "Necesita Mejora" al día siguiente de tu sprint de optimización.
¿Cuál es el cambio de mayor impacto para un sitio de listados?
En casi todos los proyectos, ha sido el TTFB. Pero el segundo más alto ha sido consistentemente remover `loading="lazy"` de las imágenes de tarjetas above-fold y agregar `fetchpriority="high"`. Juntos, esos dos elementos normalmente representan 40–60% de la mejora total del LCP. Todo lo demás es ganancias compuestas sobre esa base.loading="lazy" from above-fold card images and adding fetchpriority="high". Together those two things usually account for 40–60% of the total LCP improvement. Everything else is compounding gains on top of that foundation.
---
El trabajo de rendimiento en sitios grandes es principalmente plomería. Poco glamoroso, metódico, y profundamente satisfactorio cuando reduces un LCP de 4 segundos a 1.4 segundos y ves el tráfico orgánico aumentar dos meses después. No hay una única configuración mágica — solo una secuencia de decisiones específicas tomadas en el orden correcto.
Haz el servidor rápido. Luego haz que el elemento LCP sea descubierto y obtenido temprano. Luego quita todo lo demás de su camino.
