The first load of a page takes >4.2s, despite the fact that we are rendering heavier stuff on the client and the API responds typically in <700ms (it’s a lot of data). Subsequent loads still hit the API (which caches), but takes are less time to load despite no speed up on the server side.
I can tell this from logging in the
getServerSidePropsfunction on Vercel:
Not sure what those 8 and 9ms ones are, but it’s generally quick.
Did a recording in the browser:
WOAH that’s way too long!
Clicking on the
LCP(no indication I can click on it, and I can’t click on FCP or DCL, thanks Google) I can see this:
An image is taking that long? What’s that component?
While I’ve never had a good experience with
<Image>in NextJS (and optimization is turned off at the project level), I suspected it’s the
fallbackSrcso I changed it to a conditional
.BannerURLonly exists if we have it anyway:
Hmm… not sure that was it because if I do a first load on my local host with that new code I see a similar flame graph, with the longest being that banner still (although the visual rendering process does look a bit different now). I am thinking that is a bit of a wild goose chase, but while I wait on staging to deploy I’ll check the flame graph again.
Notably, there is one long part in the
Ah great that’s a ton of info to go off of…
Not being an expert, I look to stack overflow to the rescue:
This means that
Next.js-before-hydration, by definition, includes:
Alright, it’s time for the tried and true method: commenting shit out until it starts being fast.
I ripped out all the code that calls the
getServerSidePropsand just have. 5-line file that is
<p>hey</p>... Speed returns! e2e in 0.77s, nice!
I tried adding back in the SSR but with no depending components, and the slowness came back…
Alright, time to leave
getServerSidePropsin, but remove anything that depends on it. The only thing that it does is get the creator info (<1s), and the
_app.tsxtakes the response and sticks it in a context. At this point I’m either thinking the context is slowing it down, or the bandwidth to pass a few KB around NextJS on the server side is super slow.
getServerSidePropsonly (without dependents) is making it slow… time to remove that and see what we get. If it’s fast, next step is to remove the interception of the response in
And… It’s fast! Alright so let’s remove the propagation to the context, and try again…
getServerSideProps. Not sure if it can handle something this large (although it’s not particularly large), and I know the function gets the response in under 1s so I’m not sure what is turning it into >4s… but
Final check is to basically have it do nothing, just run and return a blank object.