useEffect useState 같은 것을 사용하지 않고 비동기 작업 가능 하다.서버에서 실행되므로, 데이터 가져오기 로직등을 서버에 두고 결과만 클라이언트에 보낼 수 있다.
서버에서 실행되므로 추가적인 API 계층 없이 데이터베이스를 직접 조회할 수 있다.
예시 . (data.ts)
export async function fetchCustomers() {
try {
const data = await sql<CustomerField>`
SELECT
id,
name
FROM customers
ORDER BY name ASC
`;
const customers = data.rows;
return customers;
} catch (err) {
console.error('Database Error:', err);
throw new Error('Failed to fetch all customers.');
}
}
이전 요청들의 완료에 의존하는 일련의 네트워크 요청 의미.
각 요청은 이전 요청이 데이터를 반환한 후에만 시작할 수 있다.
Promise.all() 또는 Promise.allSettled() 사용 해서 동시에 프로미스를 시작하는 방법.ex)
export async function fetchCardData() {
try {
const invoiceCountPromise = sql`SELECT COUNT(*) FROM invoices`;
const customerCountPromise = sql`SELECT COUNT(*) FROM customers`;
const invoiceStatusPromise = sql`SELECT
SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS "paid",
SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS "pending"
FROM invoices`;
const data = await Promise.all([
invoiceCountPromise,
customerCountPromise,
invoiceStatusPromise,
]);
// ...
}
}
하지만 ,
한개의 요청이 다른 요청보다 느리다면 성능에 문제가 생길 수 있다 .
사전에 HTML 파일을 생성하는 방식, 클라이언트에게 요청이 있을 때마다 서버로부터 전달된다.
이 과정에서 추가적인 데이터를 가져오기 위한 서버 측 코드 실행이 필요x -> 페이지 로딩 속도 빨라짐
사이트의 특정 부분만을 서버에서 렌더링하고, 나머지는 클라이언트 측에서 렌더링하는 방식
(SSR + CSR)
route를 더 작게 분리하여서 준비가 되면 서버에서 클라이언트로 점진적으로 스트리밍할 수 있는 데이터 전송 기술.
-> 모든 데이터가 로딩 될동안 페이지가 차단당하는 것을 막을 수 있다.
-> 페이지 로딩 속도 줄일 수 있다.

loading.tsxloading.tsx 파일을 만들면 됨ex) (/app/dashboard/loading.tsx)
export default function Loading() {
return <div>Loading...</div>;
}
ex)
<Suspense fallback={<RevenueChartSkeleton />}>
<RevenueChart />
</Suspense>
ex)
(page.tsx)
<Suspense fallback={<CardsSkeleton />}>
<CardWrapper />
</Suspense>
(Cards.tsx)
export default async function CardWrapper() {
const {
numberOfInvoices,
numberOfCustomers,
totalPaidInvoices,
totalPendingInvoices,
} = await fetchCardData();
...
}