Allá por 2022, un sitio de comparación de hosting llegó a mi bandeja de entrada. Gran catálogo, alrededor de 4,000 páginas, estructura de categorías profundamente anidada, enlaces de afiliados dispersos por todas partes, imágenes hero del tamaño de continentes pequeños. Su Google Search Console era un desastre. LCP sentado en 4.2 segundos en mobile. INP (que en ese entonces todavía se llamaba FID) al borde. El cliente ya había gastado £6,000 con una agencia anterior que le había tirado un CDN encima y lo había dejado ahí.
Ese proyecto es lo que eventualmente moldeó cómo pensamos sobre performance en Seahawk para sitios de alto conteo de páginas, directorios, plataformas de listados, propiedades de reseñas de hosting como construcciones estilo HostList. Lo que sigue es el playbook real.performance at 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? Un animal completamente diferente. El elemento LCP cambia dependiendo de qué página estés viendo. Un archivo de categoría tiene un candidato de LCP diferente que una página de detalle de producto, que tiene un candidato diferente que la homepage. La mayoría de las herramientas de performance reportan un único score. Ese número es una mentira, es un promedio de un conjunto wildly variado de páginas, y arreglar la homepage ignorando las 3,800 páginas de listado debajo de ella es exactamente cómo las agencias se ganan malas reputaciones.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 que los field data, lo que usuarios reales experimentan, medido en Chrome User Experience Report, es lo que Google realmente usa para señales de ranking. Los lab data de PageSpeed Insights son direccionales, no definitivos. He visto sitios puntuar 95 en PSI y aún así tener Poor LCP en datos de CrUX. 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 hero o de tarjeta sin optimizar, frecuentemente servidas a resolución completa, formato incorrecto, sin hint fetchpriority, often served at full resolution, wrong format, no
fetchpriorityhint - Scripts de terceros que bloquean render, rastreadores de afiliados, redes de publicidad, widgets de comparación cargando 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 comiendo 600-900ms antes de que la página siquiera empiece 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 "Good" antes de que el navegador haya renderizado un solo píxel. La elección de hosting y el caché 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. TTFB fue consistentemente 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 trasladé a un host WordPress administrado 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 listado (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 tocar una sola imagen.WordPress host with edge nodes in London and Frankfurt. Configured full-page caching with cache lifetimes of 12 hours on listing pages (the data didn't change that often anyway). TTFB dropped to 120-180ms on repeat requests, 280-350ms on first-hit cache misses. That single change shaved roughly 500ms off LCP before I touched a single image.
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 grilla de tarjetas, el elemento LCP es casi siempre la primera imagen de tarjeta above-the-fold, o el banner hero. El navegador tiene que descubrirla, obtenerla, decodificarla y renderizarla. Cada uno de esos pasos puede ser retrasado.
Aquí está lo que realmente hicimos en ese proyecto de HostList, en orden:
- Convertí todas las imágenes de tarjetas a WebP usando la conversión masiva de Imagify. El tamaño promedio de archivo se redujo 58% sin pérdida de calidad visible en los tamaños de miniatura de tarjeta que usábamos (280×180px de visualización, servidas 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).
- Agregué `fetchpriority="high"` a la primera imagen de tarjeta. Este único cambio redujo aproximadamente 200ms del LCP medido en WebPageTest. El navegador deja de tratarla como una imagen lazy regular y la coloca inmediatamente en la cola del escáner 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.
- Eliminé `loading="lazy"` de las primeras dos filas de imágenes de tarjetas. La carga perezosa es excelente para imágenes debajo del pliegue. En la primera fila visible, te perjudica activamente. Le dice al navegador que no descargue la imagen hasta que esté cerca del viewport, cuando ya está allí., 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 sirves la misma imagen de 1400px de ancho a un dispositivo móvil, estás quemando ancho de banda y sumando tiempo de decodificación. Usa srcset correctamente. Sé que 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 de WordPress wp_get_attachment_image() genera srcset automáticamente, pero solo si la imagen se subió con resolución suficiente 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 de ingresos de afiliación. Eso significa scripts de seguimiento 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 protocolo de enlace 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 secuenciar.
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 administradores de etiquetas), carga el Administrador de etiquetas de Google mismo con defer. Sí, esto es seguro para la mayoría de casos de uso de seguimiento 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 carga la fuente personalizada. El candidato a 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.
Uso la API de PageSpeed Insights en scripts en una muestra representativa de URLs, típicamente las 100 páginas principales por tráfico, 50 páginas de nivel de categoría y 20 páginas de catálogo profundo "delgadas". 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, dado que el campo tiende a rezagarse del lab en 10-15%)
- TBT ≤ 300ms
- CLS ≤ 0.1
Pero honestamente, para una construcción tipo HostList donde el objetivo es LCP por debajo de 1.5s, los objetivos de laboratorio necesitan ser más ajustados. 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 aplicar todo lo anterior —migración de hosting, caché de página completa, conversión de formatos de imagen, fetchpriority en candidatos de LCP, eliminación de lazy-load de filas visibles, diferimiento de scripts y auto-alojamiento de fuentes— así 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 inicio. Si tu TTFB está por encima de 500ms, ninguna cantidad de optimización de imágenes te llevará a un LCP "Good". TTFB es la base sobre la que se sienta todo lo demás. Bájalo a menos 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í, es compatible con Chrome, Edge y Safari (desde Safari 17.2). El soporte en 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 de imagen de LCP.
¿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 TTFB. Pero el segundo más alto ha sido consistentemente eliminar loading="lazy" de imágenes de tarjetas above-fold y añadir fetchpriority="high". Juntas esas dos cosas generalmente representan el 40-60% de la mejora total de LCP. Todo lo demás son ganancias compuestas sobre ese fundamento.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 que el tráfico orgánico aumenta dos meses después. No hay un único ajuste mágico, 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.
