The discussion revolves around improving the Largest Contentful Paint (LCP) metric for a Discourse site. piffy has isolated the issue to a banner theme component, which is the largest object painted on the screen for most pages. Despite prioritizing the banner image using fetchpriority="high", the image is still fetched after 2.5s, harming the LCP metric.
Falco suggests that the banner’s size may be the issue, as it is larger than the splash screen, and recommends adding a prefetch meta tag to prioritize the image’s download. However, piffy has tried this solution without success.
piffy believes that the issue is not with the image download time, but rather with the timing of the banner component’s injection into the page. They are considering converting the theme component to a plugin to address this issue.
In the meantime, piffy has implemented a temporary solution by only showing the banner to logged-in users, which has improved the LCP metric.
Other suggestions from the discussion include adjusting the banner’s size or making the splash screen animation bigger. However, piffy would prefer a solution that doesn’t compromise the aesthetic of the banner.
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
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!
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
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.
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.