Next.js Discord

Discord Forum

Nextjs Link slow to fetch page and dynamic page when i deploy on aws amplify

Unanswered
Saltwater Crocodile posted this in #help-forum
Open in Discord
Saltwater CrocodileOP
0

I am using Next.js 14.2.3 to build a website, the other pages on the website are static generated at build time and static rendered, on the other hand, i have a page or route that is dynamically rendered. On local dev, when i click on the link go to the page, "http://localhost:3000/test", it renders quickly but when this is deployed on aws amplify, and i go to the page "https://test.d2oa4hihp69p02.amplifyapp.com/test/" the page takes about 10 seconds to open and sometimes i get the error. "This page isn’t working test.d2oa4hihp69p02.amplifyapp.com took too long to respond. HTTP ERROR 504". I also have similar problems when i click on a link to view a single dynamic page within the test page https://test.d2oa4hihp69p02.amplifyapp.com/test/webstreams-medical-training-goes-global

I read and followed this part of nextjs documentation https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes. am i doing it wrongly? because it works perfectly in my local dev.

10 Replies

Saltwater CrocodileOP
Here is my server component code below,

async function Test({ searchParams, params: { lang } }) {
const query = searchParams?.query "";
const sort = searchParams?.sort
"ASC";
const industry = searchParams?.industry || "";


let casestudies = await getAllCStudies(
industry,
BATCH_SIZE,
null,
null,
null,
sort,
"DATE",
query,
lang
);

let categories = await getCaseStudyCategories("en");

return (
<div>


{casestudies.nodes.map((item) => {
return (
<div style={{ fontSize: "2rem", padding: "1rem", cursor: "pointer" }}>
<Link href={/test/${item.slug}}>
{item.title} <br />
</Link>
</div>
);
})}


</div>
);
}

export default Test;
Here are the functions that calls the endpoint

export async function getAllCStudies(
categoryName,
first,
after,
last,
before,
order,
field,
query,
lang
) {
const orderby = {
order,
field,
};

const variables = {
orderby: [{ field, order }],
first,
after,
last,
before,
query,
lang,
};

let categoryFilter = "";
if (categoryName) {
variables.categoryName = categoryName;
categoryFilter = "$categoryName: String!,";
}

const data = await fetchAPI(
query Casestudy ($orderby: [PostObjectsConnectionOrderbyInput], $first: Int, $after: String, $last: Int,$before: String, $query: String, $lang: String, ${categoryFilter}) { casestudies(where: { ${ categoryName ? "categoryName: $categoryName," : "" } orderby: $orderby, search: $query, language: $lang }, first: $first, after: $after, last: $last, before: $before) { nodes { title slug date casestudies { metatitle metadescription description companyLogo { mediaItemUrl srcSet altText } companyName mainimage { altText mediaItemUrl } } categories { nodes { id name } } } pageInfo { endCursor hasNextPage hasPreviousPage startCursor } } },
{
variables,
}
);



return data?.casestudies;
}
export async function fetchAPI(query = "", { variables } = {}) {
const res = await fetch("https://apibkofc.globalvoices.com/graphql", {
next: { revalidate: 30 },
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query,
variables,
}),
});

if (!res.ok) {
console.error(res);
return {};
}

const { data } = await res.json();

return data;
}
first things in the page component, you are doing two fetch in sequence:

async function Test({ searchParams, params: { lang } }) {
  const query = searchParams?.query  "";
  const sort = searchParams?.sort  "ASC";
  const industry = searchParams?.industry || "";


  let casestudies = await getAllCStudies(
    industry,
    BATCH_SIZE,
    null,
    null,
    null,
    sort,
    "DATE",
    query,
    lang
  );

  let categories = await getCaseStudyCategories("en");

  return (
    <div>
      {casestudies.nodes.map((item) => {
        return (
          <div style={{ fontSize: "2rem", padding: "1rem", cursor: "pointer" }}>
            <Link href={/test/${item.slug}}>
              {item.title} <br />
            </Link>
          </div>
        );
      })}
    </div>
  );
}


you can move to something in parallel using Promise.all, see the documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

with await:
let [a, b, c] = await Promise.all([promiseA, promiseB, promiseC]);
On the other part, if you are using app router, you can take use <Suspense> to your advantage to return the layout of the page and stream automatically the rest.

I've used https://buildui.com/recipes/await-component successfully to make streaming easy
Saltwater CrocodileOP
<Suspense fallback={<p>Loading casestudies...</p>}>
{casestudies.nodes.map((item) => {
return (
<div
style={{ fontSize: "2rem", padding: "1rem", cursor: "pointer" }}
>
<Link href={/test/${item.slug}}>
{item.title} <br />
</Link>
</div>
);
})}
</Suspense>

async function SingleCaseStudy({ params }) {
const { slug } = params;
let caseStudyData = await fetchCStudyBySlug(slug);

console.log(caseStudyData, "SINGLE SLUG");
return (
<div>
<h1>Single case study</h1>
<Suspense fallback={"loading casestudy..."}>
{caseStudyData.casestudy.title}
</Suspense>
</div>
);
}

export default SingleCaseStudy;

I added suspense to the page and also to the single dynamic page, i still have the same problem, please does this have to do with aws amplify, or is there another way around this?
The component under the suspense need to await
// src/app/stocks/[stockId]/page.tsx
import { Await } from "@/components/await";

export default async function Stock({
  params,
}: {
  params: { stockId: string };
}) {
  // Page blocks on this data:
  const stock = await getStock(params.stockId);

  return (
    <div>
      <h1>{stock.name}</h1>

      <Suspense fallback={<Spinner />}>
        {/* ...but renders a spinner for this slower data: */}
        <Await promise={getRecentNews(stock)}>
          {(stories) => (
            <ul>
              {stories.map((story) => (
                <li key={story.id}>{story.title}</li>
              ))}
            </ul>
          )}
        </Await>
      </Suspense>
    </div>
  );
}
Saltwater CrocodileOP
Thank you very much, this solution helped