what are we talking about today?
I wanted to demo some code changes I made today, that saw some significant improvements on the Trinity Website. I changed how I do data fetching for blog posts and filtering of the data based on tags.
Â
what’s the gist?
Well, my previous solution that did data fetching inside a
rsc
with url slugs was slow. So I moved it over to doing the data fetch in the page.tsx
and passed the data as props and saw improvements. what was wrong?
In the prior case I was calling my
getStoryData()
inside of rsc
, which even as writing this is confusing to me as to why this would make any difference in terms of speed. I was convinced I had marked the file
“use client”;
or was calling fetchData()
inside of useEffect()
But I was not, I simply had an
rsc
that took in filters via a url slug and did a data fetch inside that rsc
. I am under the assumption that the way I was passing url params into a rsc
was causing some kind of re-render that acted as a client query. I am not certain!?
Anyways, what that resulted in was a slow call that wasn’t fully utilising Next.js caching and had to be refetched for every tag click.
CODE EXAMPLES
/app/stories/[filter]/page.tsx
/components/stories/storyArea.tsx
Â
what’s the point?
I only call
getStoryData()
once inside of page.tsx
now, and every subsequent call that filters data based on tags uses the initial cached server data and does not need to do extra data fetching. Â
I did also add some
prefetch={true}
& priority={true}
on some links and images.Â
CODE EXAMPLES
/app/stories/[filter]/page.tsx
/components/stories/storyArea.tsx
/components/stories/storyArea.tsx
/components/stories/storyCard.tsx
Â
end result?
Very happy with the changes, I managed to shave off roughy 75% of load time.
Â
I do need to do some more investigation though, as the lighthouse scores do not reflect.
Â
coming back here after a refactor
I sat on this for a while and was not happy with the end result, it was good enough but so much potential room for improvement. What I initially tried to do was generateStaticParams as I was doing my data fetch at the page level with filtering via dynamic routes with url params. This however did not go to plan as static page retuned was over the Vercel 4mb threshold.
Another flaw I found was the way I was fetching Author related data to each Story; This data would be fetched per each item at the component level still on the server but a request for every item.
Â
how do we do this better?
In order to limit the refetching of data and better the caching of data this now needed to happen at a top level and only once. I now do a large fetch at the /stories page and then do filtering of that data on the client.
Â
Â
The above data is fetched on the server and on mount of our client component we set that data as a local state variable storyData and then do tag filtering on our local data.
Â
do we see improvements?
We do! quite significant improvements on page speed insights, the results on mobile are still not perfect but getting much better. In relation to the previous performance graphs above we see a lot of improvement.
other changes
I also removed all reference to prefetching as it was affecting LCP scores of the lading page.
Images were compressed via squoosh to roughly 80kb.
- This now means the images come in before their blurDataUrl’s can be calculated…
- A solution here is to store a generic base 64 image to use as the blurData
Â