Componentes temáticos y Largest Contentful Paint (LCP)

Quiero mejorar las métricas de Web Vitals de mi sitio, específicamente LCP. He tenido problemas donde el tiempo es de ~2.7s (debería ser inferior a 2.5s). De https://web.dev/optimize-lcp:

Específicamente, LCP mide el tiempo desde que el usuario inicia la carga de la página hasta que la imagen o el bloque de texto más grande se renderiza dentro de la ventana gráfica.

He aislado el problema a un componente de tema de banner que escribí. Una imagen de banner que monto como un widget “above-main-container” es el objeto más grande pintado en la pantalla para básicamente todas las páginas.

Código
<script type="text/discourse-plugin" version="0.8">
  const h = require("virtual-dom").h;

  api.createWidget("my-banner", {
    tagName: "div",

    html() {
      return  h("img.banner-center", {src: settings.banner_image, fetchpriority: "high", style: "aspect-ratio: 925 / 359 ; width: 100%"})
    }
  });
</script>

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/banner">
  {{mount-widget widget="my-banner"}}
</script>

Esto es lo que creo que está sucediendo. El div que contiene la imagen se monta usando JS, por lo que una serie de cosas prerrequisito deben suceder cuando se actualiza una página de Discourse antes de que este código JS termine de ejecutarse. Esto hace que el banner se obtenga después de 2.5s, lo que perjudica la métrica LCP.

He intentado priorizar la imagen del banner usando fetchpriority="high", como se ve en el código. Pero creo que no aborda el problema de tiempo raíz aquí.

¿Alguna sugerencia sobre cómo priorizar la renderización de este componente de tema en particular? ¿Sería mejor convertirlo en un plugin? ¿Hay alguna otra forma en que pueda inyectar el banner lo antes posible? ¡Gracias!

3 Me gusta

Quizás mi pregunta es demasiado detallada. Aquí hay una pregunta más fácil si alguien sabe la respuesta:

Cuando se recarga una página, ¿se renderizarán los elementos de los complementos antes que los componentes del tema?

Si tu banner es más grande que el elemento que usamos para el Introducing Discourse Splash - A visual preloader displayed while site assets load, vas a tener un mal momento para LCP.

Si crees que el problema principal es la descarga del activo de la imagen, puedes añadir algo como

<link rel="prefetch" href="http://example.com/myimage.webp" />

a tu elemento HEAD en un tema.

2 Me gusta

La estoy pasando mal :slight_smile: jajaja

He cambiado a usar una CDN, lo cual no ha ayudado. Como mencioné, creo que la llamada para obtener el banner es lo que sucede demasiado tarde, no el tiempo de obtención. ¡Intentaré la pre-obtención para ver si marca la diferencia!

Lo que hice mientras tanto hasta que llego a una solución es no mostrar el banner a menos que hayas iniciado sesión. Parece que Google calcula el LCP principalmente a partir del tráfico de búsqueda, que en mi caso suelen ser usuarios que no han iniciado sesión.

1 me gusta

LCP provendrá de todos los usuarios que utilicen Google Chrome, es decir, Android, Windows, MacOS, Linux y Chromebooks.

Si tienes más páginas vistas de anónimos en esos dispositivos que de usuarios registrados, sí, tu LCP reflejará el rendimiento de esos anónimos.

2 Me gusta

Bueno saberlo.

¿Crees que podría solucionar este problema haciendo más grande la animación de la pantalla de presentación?

Esto es muy complicado.

Primero, acabo de comprobar y la pantalla de presentación ya utiliza toda la pantalla (100vh y 100% de ancho).

Sin embargo, algunos usuarios no verán la pantalla de presentación si su Discourse arranca lo suficientemente rápido. Para ellos, el LCP lo establecerá el elemento que sea lo suficientemente grande. En tu caso, el banner, por lo que estás limitado por él.

Intentaría la etiqueta meta prefetch y me aseguraría de que sea un recurso muy bien optimizado y de que todos tus recursos se entreguen a través de CDN con PoPs cercanos a donde se encuentran tus usuarios.

4 Me gusta

¿Tiene que serlo?

Es básicamente un elemento básico en este momento, a los usuarios les encanta.

¿Y no se puede ajustar de ninguna manera?

Por supuesto, siempre podría encogerlo o algo así, pero preferiría una solución que no comprometa la estética.

Acabo de probar esta posible solución y, lamentablemente, no pareció marcar la diferencia. También reemplacé la imagen del banner por una imagen trivialmente pequeña como verificación de cordura y tampoco marcó la diferencia en LCP. Gracias por la sugerencia de todos modos.

No conozco el funcionamiento interno de cómo se inyectan los componentes temáticos en la página, pero mi impresión es que para cuando se inyecta el componente del banner, ya es demasiado tarde. Mi próximo intento será probarlo como un plugin.

Lejos de ser ideal, pero esto ha estado funcionando

En caso de que alguien tenga un problema similar