How increase speed of NextJS
Unanswered
California pilchard posted this in #help-forum
California pilchardOP
I have my app running but she is pretty slow and I dont know why. So I need help for best practice and maybe find the problematic part. I have this example :
https://medusa-b2c-starter-storefront.vercel.app/
Look how its fast for everything, I dont know why I dont have this.
So I just keep a basic page
And
And my middleware :
Its fast but still slower than the example, but damn why I just have a empty page and I use next-intl, is it the problem ?
https://medusa-b2c-starter-storefront.vercel.app/
Look how its fast for everything, I dont know why I dont have this.
So I just keep a basic page
/app/[lang]/page.tsx
:export default function Home() {
return (
<div>HOME</div>
)
}
And
/app/[lang]/layout.tsx
: export default async function Layout({
children,
}: RootLayoutProps) {
return (
<html suppressHydrationWarning>
<body>
{children}
</body>
</html>
);
}
And my middleware :
const intlMiddleware = createIntlMiddleware(routing);
// make a basic middleware just with intlMiddleware without Supabase auth middleware
export async function middleware(request: NextRequest) {
return intlMiddleware(request);
}
Its fast but still slower than the example, but damn why I just have a empty page and I use next-intl, is it the problem ?
43 Replies
Miniature Pinscher
Are you running the dev server or a production build?
California pilchardOP
in
dev
but I know is slower on dev
but even running the example one in dev
is still way faster than my appLike route through another page is instant
Miniature Pinscher
Are you using turbopack for both?
California pilchardOP
no turbopack
Miniature Pinscher
That could be achieved with prefetching.
California pilchardOP
But prefechting is done by default with
There is an example (first is the example in production) and second my app (in production too). Wayy slower
Link
no ?There is an example (first is the example in production) and second my app (in production too). Wayy slower
Miniature Pinscher
Yes, but only fully for static routes.
California pilchardOP
But even the refresh time is way faster in the example, isnt only prefetching right ?
Miniature Pinscher
Are you caching your fetches?
California pilchardOP
the most queries are done client side with
react-query
sooMiniature Pinscher
Well, as I said. Add prefetch to all your Links if you want the site to be as snappy as possible.
That's one major difference between your site and the other one then.
California pilchardOP
for example my movie page I do this, my
And
My query
layout.tsx
:export async function generateMetadata({
params,
}: {
params: {
lang: string;
film: string;
};
}) {
const { movie } = await getMovie(params.film, params.lang);
if (!movie) return { title: 'Film introuvable' };
return {
title: movie.title,
description: `This is the page of ${movie.title}`,
};
}
export default async function MovieLayout({
children,
params,
}: {
children: React.ReactNode;
params: {
lang: string;
film: string;
};
}) {
const { id, movie } = await getMovie(params.film, params.lang);
if (!movie) notFound();
return (
<>
<MovieHeader movie={movie as any} />
<div className="px-4 pb-4">
<MovieNavbar movieId={id} />
{children}
</div>
</>
);
};
And
page.tsx
also have the getMovie()
function :export default async function MoviePage({
params,
}: {
params: {
lang: string;
film: string;
};
}) {
const { movie } = await getMovie(params.film, params.lang);
if (!movie) notFound();
return <MovieDescription movie={movie as any} />;
}
My query
getMovie
is supposed to be share with all 3 calls right ? Liike having only one call ?export const getMovie = cache(async (id: string, lang: string) => {
/// my function
})
Miniature Pinscher
Yes.
California pilchardOP
Mine should be faster for rendering first element so ? If I have some Skeleton for loading state
Miniature Pinscher
Deduped.
Depends on if you leverage streaming.
California pilchardOP
Of my
Also I use
leverage streaming
? What do u means by that ?Also I use
cache()
but I dont really understand the difference with unstable_cache
(but when using unstable_cache
I have an error because my supabase
client use cookies()
Miniature Pinscher
You can move out the cookie accessing outside of the
unstable_cache
.As an example:
export async function getSomeQuery() {
const cookies = await cookies()
const client = someClient(cookies)
return unstable_cache(
async () =>
client.someQuery()
[],
{
tags: [`query:${client.userId}`],
revalidate: 60 * 60 * 24,
},
)();
}
Miniature Pinscher
As opposed to
unstable_cache
, cache()
is only for memoization of non-fetch functions, meaning it will only dedupe the request across the same render, not cache the data for subsequent requests.California pilchardOP
But do with
I have 3 console.logs, while with
unstable_cache
the query is made once if the function is call from multiple element (page, generateMetadata, layout) ? Because doing this :export const getMovie = (id: string, lang: string) => {
const supabase = createServerClient();
return unstable_cache(async () => {
//getting data with supabase
console.log('REQUEST MOVIE');
return {
id: movieId,
movie,
};
}, [lang, 'movie', id], {
revalidate: 60 * 60 * 24,
})();
}
I have 3 console.logs, while with
cache
only oneMiniature Pinscher
Well for one, you put the tags at the wrong place
export const getMovie = (id: string, lang: string) => {
const supabase = createServerClient();
return unstable_cache(
async () => {
//getting data with supabase
console.log("REQUEST MOVIE");
return {
id: movieId,
movie,
};
},
[],
{
revalidate: 60 * 60 * 24,
tags: [lang, "movie", id],
},
)();
};
California pilchardOP
I have the same results :
Also 3 console.log...
}, [], {
revalidate: 60 * 60 * 24,
tags: [lang, 'movie', id],
})();
Also 3 console.log...
Even with static tag like ['movie']
Miniature Pinscher
Make sure the function is marked as async
California pilchardOP
Which one ? There is the entire function :
export const getMovie = async (id: string, lang: string) => {
const supabase = createServerClient();
return unstable_cache(async () => {
const { id: movieId } = getIdFromSlug(id);
const { data: movie, error } = await supabase
.from('movie')
.select(`
*,
cast:tmdb_movie_credits(
id,
person:person(*),
role:tmdb_movie_role(*)
),
production_countries:tmdb_movie_country(
id,
country:tmdb_country(
*,
data:tmdb_country_translation(*)
)
),
spoken_languages:tmdb_movie_language(
id,
language:tmdb_language(
*,
data:tmdb_language_translation(*)
)
),
videos:tmdb_movie_videos(*)
`)
.match({
'id': movieId,
'cast.job': 'Actor',
'production_countries.country.data.language': lang,
'spoken_languages.language.data.language': lang,
'videos.iso_639_1': lang
})
.maybeSingle();
if (error) throw error;
console.log('REQUEST MOVIE');
return {
id: movieId,
movie,
};
}, [], {
revalidate: 60 * 60 * 24,
tags: [lang, 'movie', id],
})();
}
And the page where she is called :
export async function generateMetadata({
params,
}: {
params: {
lang: string;
film: string;
};
}) {
const { movie } = await getMovie(params.film, params.lang);
if (!movie) return { title: 'Film introuvable' };
return {
title: movie.title,
description: `This is the page of ${movie.title}`,
};
}
export default async function MovieLayout({
children,
params,
}: {
children: React.ReactNode;
params: {
lang: string;
film: string;
};
}) {
const { id, movie } = await getMovie(params.film, params.lang);
if (!movie) notFound();
return (
<>
<MovieHeader movie={movie as any} />
<div className="px-4 pb-4">
<MovieNavbar movieId={id} />
{children}
</div>
</>
);
};
Miniature Pinscher
That looks correct at first glance. Are you sure you're importing the right
getMovie
function?California pilchardOP
sadly yes I only have one
getMovie
function in my codeeven with this test one :
export const test = unstable_cache(async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log('THIS IS A TEST');
return 'test';
}, [], {
revalidate: 60 * 60 * 24,
tags: ['test'],
});
2 consoles logs
Miniature Pinscher
I ran your exact code snippet and I'm only getting one console log.
Which Next version are you on?
California pilchardOP
Next 14.2.16
thats crazy ahah
maybe there is something to enable for caching idk ?
Miniature Pinscher
I might be wrong, but
unstable_cache
is only supported on > 15.0California pilchardOP
ohhh well I can try upgrade
California pilchardOP
just updated to nextjs 15, same problem
California pilchardOP
simple NextJS 15 page with that :
I have no idea how u success make the test function console log once
export async function generateMetadata(
props: { params: Promise<{ lang: string; film: string; }> }
) {
const dataTest = await test();
}
export default async function PageTest(
props: {
children: React.ReactNode;
params: Promise<{
lang: string;
film: string;
}>;
}
) {
const dataTest = await test();
return (
<div className='text-black'>
test sef sef
</div>
)
};
I have no idea how u success make the test function console log once