Reputation: 2563
I am building tiny e-commerce site and have setup my index page to generate static props as well as my individual product page cause we don't have many products yet. Issue I am experiencing is very slow loading on every single user click as if I missed something crucial in how data fetching works in NextJS. So here are snippets below and full project can be found on: https://github.com/danieltosaba/framer-motion
INDEX PAGE
export default function Home({ blankets }: HomeProps) {
const classes = useStyles();
return (
<motion.div exit={{ opacity: 0 }} initial={{opacity: 0}} animate={{opacity: 1}}>
<div>
<Head>
<title>Framer Motion Transitions</title>
</Head>
<main>
<Grid container spacing={2}>
<Grid item xs={12}>
<h1>CHOOSE YOUR BLANKET</h1>
</Grid>
{blankets.map((blanket) => (
<Grid key={blanket.id} item xs={12} sm={6} lg={4}>
<Card>
<Link href="/product/[id]" as={`/product/${blanket.id}`}>
<a>
<img
src={blanket.imageUrl.cover}
alt={blanket.name}
className={classes.image}
/>
</a>
</Link>
</Card>
</Grid>
))}
</Grid>
</main>
</div>
</motion.div>
);
}
export const getStaticProps: GetStaticProps = async (ctx) => {
const response = await fetch(
"http://localhost:4001/blankets/"
);
const blankets = await response.json();
return {
props: { blankets },
};
};
PRODUCT PAGE
type ProductDetailsProps = Blanket;
export default function ProductDetails({ name, description, imageUrl, size, price }: ProductDetailsProps) {
let images = [];
imageUrl.url.forEach((img) => {
images.push({
original: img,
thumbnail: img,
});
});
return (
<motion.div
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<ImageGallery items={images} />
</Grid>
<Grid item xs={12} sm={6}>
<Paper elevation={0}>
<Card>
<CardContent>
<Typography variant="h4" gutterBottom>
{name}
</Typography>
<Typography variant="subtitle1">
Price: {price.small}
</Typography>
<Typography variant="body1" gutterBottom>
{description}
</Typography>
</CardContent>
</Card>
</Paper>
</Grid>
</Grid>
</motion.div>
);
}
export const getStaticProps: GetStaticProps = async (context) => {
const id = context.params.id;
const response = await fetch(
`http://localhost:4001/blankets/${id}`
);
const blanket = await response.json();
return {
props: blanket,
};
};
export const getStaticPaths: GetStaticPaths = async () => {
const response = await fetch(
"http://localhost:4001/blankets/"
);
const blankets: Blanket[] = await response.json();
const paths = blankets.map((blanket) => {
return { params: { id: blanket.id.toString() } };
});
return {
paths,
fallback: false,
};
};
Any help is more than welcomed!!
Upvotes: 6
Views: 4137
Reputation: 2111
The following solutions solves this problem by not pre-rendering any pages during development process.
Set environment variable SKIP_BUILD_STATIC_GENERATION
to true
for dev environments
export async function getStaticPaths() {
// When this is true (in preview environments) don't
// prerender any static pages
// (faster builds, but slower initial page load)
if (process.env.SKIP_BUILD_STATIC_GENERATION) {
return {
paths: [],
fallback: "blocking",
};
}
const posts = getAllPosts();// Could be you API request
return {
paths: posts.map((post) => {
return {
params: {
slug: post.slug,
},
};
}),
fallback: false,
};
}
Upvotes: 0
Reputation: 440
getStaticPaths will be called every single time you request a page in development. So if you have 500 products and if you are fetching all of them in getStaticPaths, means that on every page load you will loop through all of the items and you will create paths for each one of them. Just then getStaticProps will be called and your page rendered.
In production it will be different, because it will only build at "build time" and then rigenerate the pages on request from users, depending on the interval you set for the "revalidate" option.
But the best suggestion I can give is just to limit the number of data you request in getStaticPaths while developing. Hopefully we will get a better experience soon in development
Please correct me if I said anything wrong!
Upvotes: 4
Reputation: 2563
After thoroughly reading documentation I found that
In development (next dev), getStaticPaths will be called on every request.
Upvotes: 8