# Theme components and Largest Contentful Paint (LCP)

**URL:** https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680
**Category:** Development
**Created:** [March 19, 2023, 11:13pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680 "2023-03-19T23:13:26Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![piffy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/piffy/32/254198_2.png) [@piffy](https://meta.discourse.org/u/piffy)
#### Post date: [March 19, 2023, 11:13pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/1 "2023-03-19T23:13:26Z")

</div>

I’m looking to improve the web vitals for my site, specifically LCP. I have been having issues where the time is ~2.7s (should be under 2.5s). From [Optimize Largest Contentful Paint &nbsp;|&nbsp; Articles &nbsp;|&nbsp; web.dev](https://web.dev/optimize-lcp) :

> Specifically, LCP measures the time from when the user initiates loading the page until the largest image or text block is rendered within the viewport.

I have isolated the problem to a banner theme component I wrote. A banner image I mount as a widget “above-main-container” is the largest object painted on the screen for basically every page

> **Code**
>
> ```plaintext
> <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>
> 
> ```

Here’s what I think is happening. The div holding the image is mounted using JS, so a series of prerequisite things need to happen when a discourse page is refreshed before this JS code ends up running. This causes the banner to be fetched after 2.5s, thus harming the LCP metric.

I have attempted to prioritize the banner image using `fetchpriority="high"`, as seen in the code. But I think it does not address the root timing issue here.

Any suggestions on how to prioritize the rendering of this particular theme component? Would it be better to convert it to a plugin? Is there some other way I can inject the banner in as early as possible? Thanks!

---

<div class="post-metadata">

### Author: ![piffy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/piffy/32/254198_2.png) [@piffy](https://meta.discourse.org/u/piffy)
#### Post date: [March 21, 2023, 8:47pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/2 "2023-03-21T20:47:55Z")

</div>

Maybe my question is too detailed. Here’s an easier question if someone knows the answer:

When a page is reloaded, will elements from plugins render earlier than theme components?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [March 21, 2023, 9:10pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/3 "2023-03-21T21:10:51Z")

</div>

> [@piffy](#):
>
> I have isolated the problem to a banner theme component I wrote. A banner image I mount as a widget “above-main-container” is the largest object painted on the screen for basically every page

If your banner is larger than the element we use for the [Introducing Discourse Splash - A visual preloader displayed while site assets load](https://meta.discourse.org/t/introducing-discourse-splash-a-visual-preloader-displayed-while-site-assets-load/232003) you gonna have a bad time for LCP.

> [@piffy](#):
>
> I have attempted to prioritize the banner image using `fetchpriority="high"`, as seen in the code. But I think it does not address the root timing issue here.

If you think that the main issue is the download of the image asset, you can add something like

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

```

to your HEAD element in a theme.

---

<div class="post-metadata">

### Author: ![piffy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/piffy/32/254198_2.png) [@piffy](https://meta.discourse.org/u/piffy)
#### Post date: [March 21, 2023, 9:17pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/4 "2023-03-21T21:17:30Z")

</div>

I am currently having a bad time 🙂 hahaha

I’ve switched over to using a CDN which has not helped. As I mentioned, I think the call to fetch the banner is the thing happening too late, not the fetch time. I will try the prefetch to see if it makes a difference though!

What I did in the meantime until I arrive at a solution is to not show the banner unless you’re logged in. It looks like google is calculating LCP primarily from search traffic, which is typically non-logged in users in my case

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [March 21, 2023, 9:22pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/5 "2023-03-21T21:22:44Z")

</div>

> [@piffy](#):
>
> It looks like google is calculating LCP primarily from search traffic, which is typically non-logged in users in my case

LCP will come from all users using Google Chrome, so Android, Windows, MacOS, Linux and Chromebooks.

If you have more pageviews coming from anons on those devices than logged in users, yes, your LCP will reflect performance of those anons.

---

<div class="post-metadata">

### Author: ![piffy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/piffy/32/254198_2.png) [@piffy](https://meta.discourse.org/u/piffy)
#### Post date: [March 21, 2023, 9:34pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/6 "2023-03-21T21:34:15Z")

</div>

Good to know.

Do you think I could just work-around this problem by making the splash screen animation bigger?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [March 21, 2023, 9:57pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/7 "2023-03-21T21:57:53Z")

</div>

This is very complicated.

First, I just checked and the splash screen already uses the entire screen (100vh and 100% width).

However, some users won’t get the splash screen if their Discourse boot is fast enough. For those, then the LCP will be set by whatever element is big enough. In your case the banner, so you are bound by it.

I’d try the prefetch meta tag, and ensure it’s a very well optimized asset and that all your assets are delivered via CDN with PoPs close to where your users are.

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [March 21, 2023, 11:39pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/8 "2023-03-21T23:39:05Z")

</div>

> [@piffy](#):
>
> is the largest object painted on the screen for basically every page

Does it _have_ to be?

---

<div class="post-metadata">

### Author: ![piffy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/piffy/32/254198_2.png) [@piffy](https://meta.discourse.org/u/piffy)
#### Post date: [March 22, 2023, 12:00am UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/9 "2023-03-22T00:00:46Z")

</div>

It’s basically a staple at this point, the users love it

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [March 22, 2023, 12:18am UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/10 "2023-03-22T00:18:04Z")

</div>

And it can’t be adjusted in any way?

---

<div class="post-metadata">

### Author: ![piffy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/piffy/32/254198_2.png) [@piffy](https://meta.discourse.org/u/piffy)
#### Post date: [March 22, 2023, 1:47am UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/11 "2023-03-22T01:47:37Z")

</div>

Of course I could always shink it or something but I’d prefer a solution that doesn’t compromise on the aesthetic

---

<div class="post-metadata">

### Author: ![piffy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/piffy/32/254198_2.png) [@piffy](https://meta.discourse.org/u/piffy)
#### Post date: [March 22, 2023, 3:36am UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/12 "2023-03-22T03:36:07Z")

</div>

> [@Falco](#):
>
> If you think that the main issue is the download of the image asset, you can add something like
> 
> ```plaintext
> <link rel="prefetch" href="http://example.com/myimage.webp" />
> 
> ```
> 
> to your HEAD element in a theme.

I just tried out this possible solution and it didn’t seem to make a difference unfortunately. I also replaced the banner image with a trivially small image as a sanity check and it also made no difference to LCP. Thank you for the suggestion though

I don’t know the inner workings of how theme components get injected into the page but my impression is that by the time the banner component is injected, it’s already too late. My next attempt will be to try it as a plugin.

---

<div class="post-metadata">

### Author: ![piffy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/piffy/32/254198_2.png) [@piffy](https://meta.discourse.org/u/piffy)
#### Post date: [April 12, 2023, 4:54pm UTC](https://meta.discourse.org/t/theme-components-and-largest-contentful-paint-lcp/258680/13 "2023-04-12T16:54:25Z")

</div>

> [@piffy](#):
>
> What I did in the meantime until I arrive at a solution is to not show the banner unless you’re logged in

Far from ideal but this has been working

 ![Screenshot_20230412_125237](https://global.discourse-cdn.com/meta/original/4X/7/e/1/7e192f552a9ae8703c74ffbf1642b5265a3723c5.jpeg)

In case anyone has a similar issue
