how to dedup a function call used in params, metadata, and page function
Answered
Yellow-horned horntail posted this in #help-forum
Yellow-horned horntailOP
i am using an function call which uses filesystem 'fs' module and scraps all relative objects. lets call it getAllBlogPosts. now in my page route, i am using this function in generateStaticParams, generateMetadata, and also in the Page functino body, so there are total of 3 function calls.
if this were a fetch call, i would be assured that the result is cached and i would not worry about using it, but since i am using 'fs', i wonder if it is being cached, and if its not, is there any way i can dedup the function calls?
how can i dedup function call here(if its not cached?) is it okay to actually call the function three times here?
if this were a fetch call, i would be assured that the result is cached and i would not worry about using it, but since i am using 'fs', i wonder if it is being cached, and if its not, is there any way i can dedup the function calls?
export async function generateStaticParams() {
let posts = getBlogPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
export function generateMetadata({ params }) {
let post = getBlogPosts().find((post) => post.slug === params.slug);
if (!post) return;
let {
title,
publishedAt: publishedTime,
summary: description,
image,
} = post.metadata;
let ogImage = image
? image
: `${baseUrl}/og?title=${encodeURIComponent(title)}`;
return {
title,
description,
openGraph: {
title,
description,
type: "article",
publishedTime,
url: `${baseUrl}/blog/${post.slug}`,
images: [
{
url: ogImage,
},
],
},
twitter: {
card: "summary_large_image",
title,
description,
images: [ogImage],
},
};
}
export default function Blog({ params }) {
let post = getBlogPosts().find((post) => post.slug === params.slug);
if (!post) {
notFound();
}
const toc = parseToc(post.content);
return(<div></div>)how can i dedup function call here(if its not cached?) is it okay to actually call the function three times here?
12 Replies
Yellow-horned horntailOP
from my understandings, the call in
generateStaticParams is going to be only called in build time and no more in run time, so excluding that, the remaining two function calls are called on runtime. if its correct, is it okay to call the same functoin twice here?@joulev Use React.cache to dedupe the function call
Yellow-horned horntailOP
i haven thought about that. thanks.so 'fs' calls are not cached, right?
another question is, if i use 'cache' is it ok to declare the cache function outside of the nextjs function, say globally?
like this:
another question is, if i use 'cache' is it ok to declare the cache function outside of the nextjs function, say globally?
like this:
const postCache = cache(getBlogPosts);
export async function generateStaticParams() {
let posts = postCache();
return posts.map((post) => ({
slug: post.slug,
}));
}
export function generateMetadata({ params }) {
let post = postCache().find((post) => post.slug === params.slug);
if (!post) return;
let {
title,
publishedAt: publishedTime,
summary: description,
image,
} = post.metadata;
let ogImage = image
? image
: `${baseUrl}/og?title=${encodeURIComponent(title)}`;
return {
title,
description,
openGraph: {
title,
description,
type: "article",
publishedTime,
url: `${baseUrl}/blog/${post.slug}`,
images: [
{
url: ogImage,
},
],
},
twitter: {
card: "summary_large_image",
title,
description,
images: [ogImage],
},
};
}if so, if i am in a different file of the same route, say 'layout.tsx' or 'template.tsx', can i import the cached function?
American Crow
I think you are trying to achieve a similar thing i did couple of weeks ago.
I am guessing it's about mdx files read from disk and statically generated?
Pretty sure
When i remember correctly i ended up successfully caching the data read from the fs however when my mdx files exceeded 1.000 files i quickly ran out of memory, which makes sense. So that stuff being on disk and not in memory actually makes some sense.
Sorry for not awnsering your question directly
I am guessing it's about mdx files read from disk and statically generated?
Pretty sure
generateMetadatais also only called on build when combined with generateStaticParams. So the 2 functions you are trying to cache reduce to one (which doesnt make sense ofc.).When i remember correctly i ended up successfully caching the data read from the fs however when my mdx files exceeded 1.000 files i quickly ran out of memory, which makes sense. So that stuff being on disk and not in memory actually makes some sense.
Sorry for not awnsering your question directly
(I ended up not caching anything)
American Crow
The rules fo React.cache are the following:
Globally is okay. But it has to be the same request
- React will invalidate the cache for all memoized functions for each server request.
- Each call to cache creates a new function. This means that calling cache with the same function multiple times will return different memoized functions that do not share the same cache.
- cache is for use in Server Components only.Globally is okay. But it has to be the same request
@American Crow I think you are trying to achieve a similar thing i did couple of weeks ago.
I am guessing it's about mdx files read from disk and statically generated?
Pretty sure `generateMetadata`is also only called on build when combined with `generateStaticParams`. So the 2 functions you are trying to cache reduce to one (which doesnt make sense ofc.).
When i remember correctly i ended up successfully caching the data read from the fs however when my mdx files exceeded 1.000 files i quickly ran out of memory, which makes sense. So that stuff being on disk and not in memory actually makes some sense.
Sorry for not awnsering your question directly
frankly speaking, when there are that many files, i would use a CMS rather than the file system
but yeah, cache takes resources so if you cache too many things, it will break one way or another
@joulev but yeah, cache takes resources so if you cache too many things, it will break one way or another
American Crow
yea you are right i was kind of limit testing and realized i am optimizing a system which was not designed for that. Just shared it in case OP is going down the same rabbit hole
Yellow-horned horntailOP
that surely helped a lot. thanks legends!