NextJS High LPC (Large Content Paint)

Hey, I'm dealing with a problem on my NextJS site where my LPC score is between 3-4 seconds. I've gotten it down to around ~2 seconds by removing google analytics, posthog analytics, client components, and sentry now I'm adding things back to see what the problem is. Source code: https://github.com/answeroverflow/answeroverflow Testing method is removing everything from the site, and then building and starting a production verison locally LCP Improvements List: - Removing tremor safelist reduced css bundle by 50% - Using <a> instead of next/link took .3s off of LPC - Lazy loading avatar images, kept LPC at 2.2 LCP Deprovements List: - GA 2.2->2.5 - Google Fonts 2.2->2.7
GitHub
GitHub - AnswerOverflow/AnswerOverflow: Indexing Discord Help Chann...
Indexing Discord Help Channel Questions into Google - GitHub - AnswerOverflow/AnswerOverflow: Indexing Discord Help Channel Questions into Google
No description
103 Replies
Rhys
RhysOP•14mo ago
(not really looking for support btw just for clarifying, this is mainly a thread for me to add things back to see what makes it take longer and i want it indexed but if have suggestions i'll take them blobhug )
Rhys
RhysOP•14mo ago
Empty page, 1.7-1.9 seconds
No description
Rhys
RhysOP•14mo ago
Result page, recommendations only no client components
No description
Rhys
RhysOP•14mo ago
I'd expect this to have an LPC that's the same as empty page
Rhys
RhysOP•14mo ago
Removing the links brings the LPC down, weird
No description
Rhys
RhysOP•14mo ago
No <Link/> vs <Link>
No description
Rhys
RhysOP•14mo ago
cc @Josh do you use next/link?
Josh
Josh•14mo ago
I do indeed
Rhys
RhysOP•14mo ago
this is crazy, it adds like .3 seconds onto my LCP - that can't be right can it?
No description
Rhys
RhysOP•14mo ago
This is on Next 14 so as up to date as possible
Josh
Josh•14mo ago
I mean it is technically Js
Rhys
RhysOP•14mo ago
I'm not using prefetching so I don't see much reason to have it, may evaluate adding it back in the future Will probably revaluate it since in a realworld test it may not affect it
Rhys
RhysOP•14mo ago
adding server invite to the page, adds .3s to LPC due to radix use client
No description
Josh
Josh•14mo ago
Using next/link let's it do router based navigation instead of full page reloads, so you definitely still want it
Rhys
RhysOP•14mo ago
Somehow in dev mode I got a LCP of 1.4, not sure how exactly
No description
Josh
Josh•14mo ago
Interesting
Rhys
RhysOP•14mo ago
I might keep it off of high use pages that people don't navigate off of, i.e the result pages w/ server components i can send <a> vs <link> depending on if prefetch is passed
Rhys
RhysOP•14mo ago
0 JS icons w/ adding back server invite keeps LPC below 2 - i need to figure out how to do a 0 JS fallback image incase they error
No description
Rhys
RhysOP•14mo ago
even with 0 js server invite + icon it's still gone up to 2.1s, this is still with no client components
No description
Rhys
RhysOP•14mo ago
had a left over client component, just one client component is adding .3s to LPC that may just be an overall cost to hit with adding client components however, not an exponential growth
Rhys
RhysOP•14mo ago
Added everything back, got an LPC of 1.9
No description
Rhys
RhysOP•14mo ago
2.2
No description
Rhys
RhysOP•14mo ago
Pretty consistently 1.9-2.2, not much impact bringing back the full page which is good
Rhys
RhysOP•14mo ago
Adding search bar client component, no perf impact - staying between 1.8 and 2.2
No description
No description
Rhys
RhysOP•14mo ago
Added back footer, no impact to LPC staying between 1.8-2.2
No description
Rhys
RhysOP•14mo ago
added back discord avatars since i forgot them, slight jump in LCP to 2.3-2.4 max
No description
No description
Rhys
RhysOP•14mo ago
It's a server component though, and these are loading w/ eager and fetch prority high
Rhys
RhysOP•14mo ago
added DNS prefetch to cdn.discordapp.com, doesn't impact LPC much
No description
Rhys
RhysOP•14mo ago
we're also in the danger range now for LPC
No description
Rhys
RhysOP•14mo ago
Going to try adding the navbar back next, I'm expecting that to impact LPC quite a lot
Rhys
RhysOP•14mo ago
LCP up to 2.7 with the navbar
No description
Rhys
RhysOP•14mo ago
blank page ~2-2.1
No description
Rhys
RhysOP•14mo ago
shadcn navbar is nice but i dont really need it i can just make the same with raw html
Rhys
RhysOP•14mo ago
0 js navbar, 2.5s LPC
No description
Rhys
RhysOP•14mo ago
i dont get it
Rhys
RhysOP•14mo ago
taking the page content away and we're back down to 1.7
No description
Rhys
RhysOP•14mo ago
might be taking a long time to load the discord icons?
Rhys
RhysOP•14mo ago
Bringing page back puts it at 2.4, not sure what element is causing that
No description
Rhys
RhysOP•14mo ago
Problem element seems to be server invite, removing that improves LPC
No description
Rhys
RhysOP•14mo ago
these are client components with a tracking event for analytics maybe i can lazy load them so they don't block
Rhys
RhysOP•14mo ago
yes server invite increases LPC
No description
Rhys
RhysOP•14mo ago
For some reason when it loads from the initial load instead of the cached load LPC is always a lot lower
No description
Rhys
RhysOP•14mo ago
Removing client component and server icon improves LPC by .1-.2s
No description
Rhys
RhysOP•14mo ago
literally only server icon is 2.5s for LPC
No description
Rhys
RhysOP•14mo ago
Removing server icon brings it down consistently to 2.2s ish still high, itd be nice to get it closer to the empty page at 1.8 for more buffer room
Rhys
RhysOP•14mo ago
Removing the avatar icon brings it down to 1.9-2.0 ish so image loading is definetly an issue
No description
Rhys
RhysOP•14mo ago
Not sure how to improve that, tried eager loading & lazy loading, already preconnceting to discords' cdn
Rhys
RhysOP•14mo ago
2-2.2s LPC when adding the analytics loader back to the server invite
No description
Rhys
RhysOP•14mo ago
tried eager loading emojis, made LPC worse
No description
Rhys
RhysOP•14mo ago
As an aside, I think it'd be worth creating a quick project in Astro to see if loading the same amount of JS is faster
vae
vae•14mo ago
😭
Rhys
RhysOP•14mo ago
im struggling 😦 this really seems like it shouldnt be this impactful, all i want to load is a bit of javascript and some images why is this so difficult
Rhys
RhysOP•14mo ago
Setting prority low and lazy loading on avatar images appears to have helped with LPC, sitting at around 2.2 at the moment
No description
Rhys
RhysOP•14mo ago
Pretty consistently getting 2.2 LPC now with lazy loading avatar images, that seesm to be a key improvement current baseline: 2.2 LPC
Rhys
RhysOP•14mo ago
Added the searchbar client component back, still at 2.2
No description
Rhys
RhysOP•14mo ago
That gives enough of a buffer to bring the rest of the navbar back Gonna do a quick test adding google analytics back and seeing what happens Added Google analytics Run 1 - 2.1 Run 2 - 2.5 Run 3 - 2.5 Run 4 - 2.5
Rhys
RhysOP•14mo ago
No description
Rhys
RhysOP•14mo ago
That's a concerning .3 jump - real world experience may be different on that one though Quick test with next/third-parties Run 1 - 2.4 Run 2 - 2.5 Run 3 - 2.5 Not really any different This is with preconnect as well test
Rhys
RhysOP•14mo ago
No description
Rhys
RhysOP•14mo ago
Even Clyde is concerned about my LPC score Adding Google Fonts LPC jumps up to 2.7 which is really concerning
Rhys
RhysOP•14mo ago
here's the font config, i should go through and make sure im only importing weights i use
No description
Rhys
RhysOP•14mo ago
reverting shows that yes it makes a difference
No description
Rhys
RhysOP•14mo ago
going to try importing one weight of one font and going from there
Rhys
RhysOP•14mo ago
adding one font of one weight raises LPC to ~2.4
No description
Rhys
RhysOP•14mo ago
Two fonts, one weight each brings LPC to 2.6s Data Unlocker 2-2.4s Dang, yeah that's adding around .2s to LCP That one is a really valuable script to have though, not sure how to get around that Data Unlocker is inconsisent, between 2.0 and 2.4 - I'll keep it for now and move the baseline to 2.4 New Baseline 2.4 Time to test out adding posthog back, i know that one is gonna be rough im lazy loading it though so maybe just maybe it wont increase lpc PostHog No impact on perf 🙌 staying between 2.2-2.5 - bundle size did get 49 kb unused added to it but again, lazy loading thats fine
Rhys
RhysOP•14mo ago
Interestingly, the blank page is staying at 1.8 for LCP
No description
Rhys
RhysOP•14mo ago
Next-Themes Testing out adding Next themes now, unsure how this will impact perf but if it has a major impact i can make a basic version that doesn't wrap the app in use client
Rhys
RhysOP•14mo ago
Next themes stays around 2.4 so in baseline
No description
Rhys
RhysOP•14mo ago
Time to add back the rest of the navbar
Rhys
RhysOP•14mo ago
Header Adding back the rest of the header brings blank page up to 2.1
No description
Rhys
RhysOP•14mo ago
real page is up to 3.1
No description
Rhys
RhysOP•14mo ago
😦 my gut feeling is next is bundling imports that are used in server components files even if they aren't sent to the client which would be bad
Rhys
RhysOP•14mo ago
Treemap with unused imports vs with unused imports deleted
No description
No description
Rhys
RhysOP•14mo ago
LCP without sign in button is up to 2.6
No description
Rhys
RhysOP•14mo ago
LCP with navbar with sign in button, 2.4-2.6
Rhys
RhysOP•14mo ago
No description
Rhys
RhysOP•14mo ago
Very consistently /empty is between 1.9s and 2s to load
No description
Rhys
RhysOP•14mo ago
So that means there's .5s that can be saved on /m/[id] Current State: LPC 2.6 Missing: Required: - Signed in dropdown - Tremor Tailwind Config - twMerge Optional: - Google fonts - Google analytics - Next/Link - error state for avatar
Josh
Josh•14mo ago
I don't think it is, I actually just had a case where I was importing something with side effects to being imported, and it only got triggered when I referenced the import in the site
Rhys
RhysOP•14mo ago
Here's where I'm importing it - changed it to a dynamic import and it's still loading really weird
No description
No description
Rhys
RhysOP•14mo ago
even with dynamic moved after the if statement it still loads the js
No description
ATOMowy_grzyb
ATOMowy_grzyb•14mo ago
just a Q, with a fast FCP (0.9s) and plenty of content on the page already as seen on the snapshots, is that LCP a problem? The page isn't blocked in between, is it. It's just that a piece of it is loading slower
Rhys
RhysOP•14mo ago
It’s a problem because Google sees the high LCP and then sometimes doesn’t show my site in search results for mobile users - if that wasn’t a factor I wouldn’t really be worried about it But there’s like a noticeable drop in impressions on mobile so I gotta fix it
ATOMowy_grzyb
ATOMowy_grzyb•14mo ago
I was going to say
oh so this might suck for partial prerender, because until all the suspended stuff gets streamed into the document, it's counting that as LCP, so on simple POC for partial prerender with some delays added to the fetches on a couple of components I'm seeing all orange on LCP
but I just did something that fixed it and I got 0.3s FCP and 0.7s LCP, so never mind I guess
Rhys
RhysOP•14mo ago
What confuses me is how LCP is calculated, since in the screenshots the largest content area is painted immediately I’m wondering if it’s next hydrating the page with react that’s causing it to think the html changed when in reality nothing changed
ATOMowy_grzyb
ATOMowy_grzyb•14mo ago
yeah idk myself, I was just getting 5s+ LCP because I have a 3s artificial delay on suspended component and it was seeing that pop in as LCP, but I fixed a bunch of layout shift issues and it's now down 0.6s - either chrome is being funky or idk it was my assumption that it was hydration or the suspense landing from the stream, but I was wrong it was seeing a huge ass carousel that was popping in as the LCP element, but after I fixed layout shift between a placeholder and the actual carousel (the one with delayed suspense) it now reports a hero image as the LCP element so maybe look in the report because it spells out what the LCP element is @Rhys as reece
ATOMowy_grzyb
ATOMowy_grzyb•14mo ago
No description
ATOMowy_grzyb
ATOMowy_grzyb•14mo ago
could be something stupid like my layout shift problem
Rhys
RhysOP•14mo ago
in this case it's the CTA button at the bottom
No description
Rhys
RhysOP•14mo ago
in this one it's the message content
No description
ATOMowy_grzyb
ATOMowy_grzyb•14mo ago
so looks like it's not one big thing that contributes to the LCP, but rather bunch of small things that get painted at once?
Rhys
RhysOP•14mo ago
Yeah, it's not like a large image It could be a large image if there's an attachment
ATOMowy_grzyb
ATOMowy_grzyb•14mo ago
I mean it's not about how large it is, but if what it highlights actually contributes anything major
Rhys
RhysOP•14mo ago
https://www.answeroverflow.com/m/1167312424563658773 For this thread, LPC is also the content
NextJS High LPC (Large Content Paint) - Theo's Typesafe Cult
Hey, I'm dealing with a problem on my NextJS site where my LPC score is between 3-4 seconds. I've gotten it down to around ~2 seconds by removing google analytics, posthog analytics, client components, and sentry now I'm adding things back to see what the problem is. Source code: https://github.com/answeroverflow/answeroverflow Testing method ...
No description
Rhys
RhysOP•14mo ago
Which is good at least, the content is the most relevant part
ATOMowy_grzyb
ATOMowy_grzyb•14mo ago
if it highlights an element that on its own is a second then you know where to look, if it shows 20 different things each time and they have small amount of ms to them, then well
Rhys
RhysOP•14mo ago
this is interesting looking at the tree map, as the number of elements on the page grows the number of script tags nextjs has to add to hydrate the page grows
No description
Rhys
RhysOP•14mo ago
i figure thats probably having a large impact, but that's just how next works so i cant exactly solve that Maybe instead of loading all thread messages I just load like the first 10 and load more on scroll that's how reddit does it
Rhys
RhysOP•14mo ago
No description
shikishikichangchang
shikishikichangchang•14mo ago
@Rhys as reece how do yo use lighthouse on pages that are protected by auth (must be authenticated to view)
Rhys
RhysOP•14mo ago
i don't since i don't care about those pages since it doesn't affect my website score with google Baseline: 4s LCP Knowing what I know now, I'm going to start from the beginning at try to get LPC down to 3 from now Removing tremor from css file - 3.8-3.9 LCP Old CSS file info: 34.9 KiB 300 ms New CSS file info:
11.4 KiB 150 ms Removing tw-merge from client components - LCP 3.8 -> 3.4-3.7 LCP hard to tell Mainly stays around 3.9 LCP, Bundle size: Before: 846.4 KiB After: 821.2 KiB It's decently possible to enforce these are only used on server, but there may be easier optimizations else where (also what in the world is causing 820 kb of JS) Using <a> instead of next/link - LCP 3.8 -> LCP 3.4-3.7 Bundle Size: Before: 846.4 KiB After: 823.2 KiB I know exactly what is happened to jump the LCP timing, next/link is used inside of the LCP content, that requires JS, it doesn't run for a while, and then it runs - may be time to ditch next link Removing client component from avatar images - TODO LCP Lazy loading avatars - Insignificant Removing useless navbar JS - 3.4-3.8 -> 3.1 consistently Before: 823.2 KiB After: 680.6 KiB This is gonna suck to improve Only importing used font weights - TODO LCP Prority fetching emojis: LCP 3.1 -> 2.9-3.2
shikishikichangchang
shikishikichangchang•14mo ago
Hmm isn’t the point of a good score to give users a good experience? Or is there some other reason I’m not aware of
BOLT04
BOLT04•14mo ago
hi @Rhys as reece if you want take a look at these videos, they help quite a lot on understanding and optimizing LCP 😀 https://www.youtube.com/watch?v=fWoI9DXmpdk https://www.youtube.com/watch?v=AQqFZ5t8uNc
Chrome for Developers
YouTube
A deep dive into optimizing LCP
There is no shortage of advice on the web about improving page load performance, and yet, of the three Core Web Vitals, Largest Contentful Paint (LCP) is still the hardest metric for most sites to consistently meet the recommended "good" threshold. This talk looks at what makes LCP a hard metric to optimize, and offers some concrete strategies t...
Chrome for Developers
YouTube
Optimize for Core Web Vitals
In this hands-on talk, we cover tips & tricks for optimizing your user-experience to meet the Core Web Vitals. We use tools like Lighthouse & DevTools, show you code snippets for fixes, and highlight how you too can get fast and stay fast. Optimizing for quality of user experience is key to the long-term success of any site on the web. Whether ...
Want results from more Discord servers?
Add your server