#Slow Next.js Starter Pack

19 messages · Page 1 of 1 (latest)

hazy hull
#

Hey everyone!
I've recently switched to the new Next.js Starter Pack (with server actions) and have noticed my site running significantly slower than the previous one. I suspect there might be an issue with the Next.js caching system (https://nextjs.org/docs/app/building-your-application/caching). For instance, in local development, my category page load is generating 2 API calls (one for the metadata and one for the page), whereas, if I understand the Next.js documentation correctly, it should only be making one call due to caching and the Next.js tags mecanism.

// src/app/categories/[handle]/page.tsx
export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const category = await getCategoryByHandle(params.handle)

  if (!category) {
    notFound()
  }

  const metadata = {
    title: `${category.name}`,
    description: `${category.description}`,
  } as Metadata

  return metadata
}

export default async function CategoryPage({ params }: Props) {

  const category = await getCategoryByHandle(params.handle)

  if (!category) {
    notFound()
  }

  return <CategoryTemplate category={category} />
}
export const getCategoryByHandle = cache(async function (
  handle: string
): Promise<ProductCategory> {
  const category = await medusaClient.productCategories
    .list({ handle: handle }, { next: { tags: ['categories'] } })
    .then(({ product_categories }) => product_categories[0])
    .catch((err) => {
      throw err
    })

  return category
})

What are your thoughts on this? Has anyone else experienced similar issues or have any insights on how to resolve this caching problem? Appreciate any help or advice you can provide!

#

I'm encountering this issue across all my API calls to the backend via the Medusa Client. It's significantly slowing down my application, especially in terms of server actions. For example, my add to cart action is a server action, and once submitted, I see in the logs that all the API calls are regenerated

earnest estuary
#

afaik the cache is react and and revalidateTag is next/cache, cache is executing the api call when first called and from the second it is supposed to return the memorized function

hazy hull
#

What I thought I understood by using this method was that the server was hit only once since the request was tagged with 'categories' via Next tag, and that the React cache would prevent the duplication of the request, but that doesn't seem to be the case.
As seen in the server logs:

::1 - - [11/Mar/2024:10:19:51 +0000] "GET /store/product-categories?handle=xxx HTTP/1.1" 200 2624 "-" "axios/0.24.0"
::1 - - [11/Mar/2024:10:19:51 +0000] "GET /store/product-categories?handle=xxx HTTP/1.1" 200 2624 "-" "axios/0.24.0"

If I remove the generateMetadata, I indeed only have one line.

Not being a Next.js expert, I was wondering if I might have missed some kind of configuration.

#

I used the product categories as an example, but it's an issue I'm facing across the entire app when using Medusa from import Medusa from '@medusajs/medusa-js', which itself uses Axios. Should I switch to custom implementations using fetch as recommended in the Next.js documentation?

hazy hull
#

It works when I switched to fetch as follow :

export const getCategoryByHandle = cache(async function (
  handle: string
): Promise<ProductCategory> {
  const result = await fetch(
    `${process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL}/store/product-categories?handle=${handle}`,
    {
      next: {
        revalidate: 3600,
        tags: ['categories'],
      },
    }
  ).then((res) => res.json())

  const category = result.product_categories[0]

  return category
})
#

If I understand correctly, the caching system with the Next.js starter pack doesn't really work because it uses @medusajs/medusa-js?

earnest estuary
#

We need to check if the requests remain the same all the time using medusaClient

shell crown
earnest estuary
hazy hull
#

I'm using the caching mechanism cache(), exactly as implemented in the Next.js Starter Pack (https://github.com/medusajs/nextjs-starter-medusa/blob/22a54f431fffaf1a1d070d4f78ac9a93215ac632/src/lib/data/index.ts#L699). My first method getCategoryByHandle above utilizes it (from import { cache } from 'react'), but it doesn't seem to work with @medusajs/medusa-js.

GitHub

A performant frontend ecommerce starter template with Next.js 14 and Medusa. - medusajs/nextjs-starter-medusa

earnest estuary
#

but this cache works only within one request

#

"React will invalidate the cache for all memoized functions for each server request."

#

I feel there are few misunderstanding along the way 🙂 this cache allows to use the same memorized call within a request, but not across requests.

#

basically if you have 2 components using the same data only one call will be initiated the second will use the memorized

hazy hull
#

Yes, I think I misunderstood! Thank you for your explanations! What I don't quite understand in this case is why I have multiple requests triggered in this kind of code where I have a <Header> component and a <Footer> component in my layout, both loading the same function:

export const getCategoriesList = cache(async function()... 

containing

await medusaClient.productCategories.list({}, { next: { tags: ['categories'] } })
``` which loads twice per page on pages and server action.
earnest estuary
#

You have to await getCategotiesList and both should be on server side

#

It is possible that the medusaclient is adding something to the header which makes them different, never tested to be honest

hazy hull
#

Ok, I'll check all that in this case, thank you for your response!
The mechanics of Next.js are not necessarily easy to grasp and debug.