Компоненты темы и Largest Contentful Paint (LCP)

Я хочу улучшить показатели Web Vitals для моего сайта, в частности LCP. У меня возникли проблемы: время составляет ~2,7 с (должно быть менее 2,5 с). Согласно https://web.dev/optimize-lcp:

В частности, LCP измеряет время от момента, когда пользователь инициирует загрузку страницы, до момента рендеринга самого большого изображения или текстового блока в области просмотра.

Я изолировал проблему в компоненте темы баннера, который написал. Изображение баннера, которое я монтирую как виджет «above-main-container», является самым большим объектом, отображаемым на экране практически на каждой странице.

Код
<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>

Вот что, по моему мнению, происходит. div, содержащий изображение, монтируется с помощью JS, поэтому при обновлении страницы Discourse должен произойти ряд предварительных действий, прежде чем этот код JS выполнится. Из-за этого баннер загружается после 2,5 с, что негативно сказывается на метрике LCP.

Я пытался приоритизировать загрузку изображения баннера с помощью fetchpriority="high", как показано в коде. Но, думаю, это не решает проблему с таймингом в корне.

Есть ли предложения, как приоритизировать рендеринг этого конкретного компонента темы? Было бы лучше конвертировать его в плагин? Есть ли другой способ внедрить баннер как можно раньше? Спасибо!

Возможно, мой вопрос слишком детальный. Вот более простой вопрос, если кто-то знает ответ:

При перезагрузке страницы элементы плагинов будут отображаться раньше компонентов темы?

Если ваш баннер больше элемента, который мы используем для Introducing Discourse Splash - A visual preloader displayed while site assets load, у вас будут проблемы с LCP.

Если вы считаете, что главная проблема — это загрузка файла изображения, вы можете добавить что-то вроде

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

в элемент HEAD вашей темы.

У меня сейчас не очень :slight_smile: hahaha

Я перешёл на использование CDN, но это не помогло. Как я уже говорил, я думаю, что проблема не во времени выполнения запроса fetch для баннера, а в том, что сам запрос запускается слишком поздно. Хотя я попробую использовать prefetch, чтобы посмотреть, изменит ли это что-то!

Тем временем, пока я не нашёл окончательное решение, я сделал так, чтобы баннер показывался только авторизованным пользователям. Похоже, что Google в основном рассчитывает LCP по трафику из поисковых систем, а это в моём случае обычно пользователи, не вошедшие в систему.

LCP формируется на основе данных от всех пользователей, использующих Google Chrome, то есть на Android, Windows, macOS, Linux и Chromebook.

Если у вас больше просмотров страниц от анонимных пользователей на этих устройствах, чем от авторизованных, то да, ваш LCP будет отражать производительность именно для этих анонимных пользователей.

Хорошо, что это известно.

Как вы думаете, можно ли обойти эту проблему, увеличив анимацию загрузочного экрана?

Это очень сложно.

Сначала я проверил: экран загрузки уже занимает весь экран (100vh и 100% ширины).

Однако некоторые пользователи не увидят экран загрузки, если запуск Discourse у них достаточно быстрый. В таком случае LCP будет определяться любым элементом, который достаточно велик. В вашем случае это баннер, поэтому вы ограничены им.

Попробуйте использовать мета-тег prefetch, убедитесь, что это сильно оптимизированный ресурс, и что все ваши ресурсы доставляются через CDN с точками присутствия (PoPs), расположенными близко к вашим пользователям.

Должно ли оно обязательно быть таким?

На данный момент это уже стало неотъемлемой частью, пользователям это очень нравится

И его нельзя отрегулировать каким-либо образом?

Конечно, я всегда могу уменьшить его или что-то в этом роде, но я предпочитаю решение, которое не идет в ущерб эстетике.

Я только что попробовал это возможное решение, но, к сожалению, оно, похоже, не дало никакого эффекта. Я также заменил баннерное изображение на очень маленькое для проверки, и это тоже не повлияло на LCP. Тем не менее, спасибо за предложение.

Я не знаю, как именно компоненты темы внедряются в страницу, но у меня сложилось впечатление, что к моменту внедрения компонента баннера уже слишком поздно. Следующей попыткой будет попробовать реализовать это в виде плагина.

Это далеко не идеально, но пока работает

На случай, если у кого-то возникнет похожая проблема