이전 장에서는 대시보드 개요 페이지에 대한 데이터를 가져왔습니다. 그러나 현재 설정의 두 가지 제한 사항에 대해 간략하게 논의했습니다.
정적 렌더링을 사용하면 빌드 시(배포 시) 또는 재검증 중에 데이터 가져오기 및 렌더링이 서버에서 발생합니다. 결과는 CDN(Content Delivery Network)에 배포 및 캐시될 수 있습니다.

사용자가 애플리케이션을 방문할 때마다 캐시된 결과가 제공됩니다. 정적 렌더링에는 몇 가지 이점이 있습니다.
정적 렌더링은 정적 블로그 게시물이나 제품 페이지와 같이 사용자 간에 공유되는 데이터나 데이터가 없는 UI에 유용합니다. 정기적으로 업데이트되는 개인화된 데이터가 있는 대시보드에는 적합하지 않을 수 있습니다.
정적 렌더링의 반대는 동적 렌더링입니다.
동적 렌더링을 사용하면 요청 시 (사용자가 페이지를 방문할 때) 각 사용자의 콘텐츠가 서버에서 렌더링됩니다. 동적 렌더링에는 몇 가지 이점이 있습니다.
기본적으로 @vercel/postgres는 자체 캐싱 의미 체계를 설정하지 않습니다. 이를 통해 프레임워크는 자체 정적 및 동적 동작을 설정할 수 있습니다.
서버 구성 요소 내부에서 호출되는 Next.js API unstable_noStore나 데이터 가져오기 기능을 사용하여 정적 렌더링을 거부할 수 있습니다. 이것을 추가해 보겠습니다.
data.ts에서, next/cache로부터 unstable_noStore를 가져오고, 데이터 가져오기 함수의 최상위에 호출합니다.
// ...
import { unstable_noStore as noStore } from 'next/cache'; // noStore 불러오기
export async function fetchRevenue() {
// 응답이 캐시되지 않도록 하려면 여기에 noStore()를 추가합니다.
// 이 값은 fetch(..., {cache: 'no-store'})와 같습니다.
noStore(); // 호출하기
// ...
}
export async function fetchLatestInvoices() {
noStore(); // 호출하기
// ...
}
export async function fetchCardData() {
noStore(); // 호출하기
// ...
}
export async function fetchFilteredInvoices(
query: string,
currentPage: number,
) {
noStore(); // 호출하기
// ...
}
export async function fetchInvoicesPages(query: string) {
noStore(); // 호출하기
// ...
}
export async function fetchFilteredCustomers(query: string) {
noStore(); // 호출하기
// ...
}
export async function fetchInvoiceById(query: string) {
noStore(); // 호출하기
// ...
}
참고: unstable_noStore는 실험적인 API이며 향후 변경될 수 있습니다. 자신의 프로젝트에서 안정적인 API를 사용하려는 경우 세그먼트 구성 옵션인 export const dynamic = "force-dynamic"을 사용할 수도 있습니다.
대시보드를 동적으로 만드는 것이 좋은 첫 번째 단계입니다. 그러나... 이전 장에서 언급한 한 가지 문제가 여전히 남아 있습니다. 하나의 데이터 요청이 다른 모든 데이터 요청보다 느리면 어떻게 되나요?
느린 데이터 가져오기를 시뮬레이션해 보겠습니다. data.ts 파일에서 .console.log 및 setTimeoutfetchRevenue() 내부의 주석 처리를 제거합니다.
export async function fetchRevenue() {
try {
// 데모 목적으로 응답을 인위적으로 지연합니다.
// 프로덕션에서 이 작업을 수행하지 마세요 :)
console.log('Fetching revenue data...'); // 콘솔 찍기
await new Promise((resolve) => setTimeout(resolve, 3000)); // 느린 데이터 가져오기
const data = await sql<Revenue>`SELECT * FROM revenue`;
console.log('Data fetch completed after 3 seconds.'); // 콘솔 찍기
return data.rows;
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch revenue data.');
}
}
이제 http://localhost:3000/dashboard/ 를 엽니다.새 탭에서 페이지를 로드하는 데 시간이 얼마나 오래 걸리는지 확인하세요. 터미널에는 다음 메시지도 표시됩니다.
Fetching revenue data...
Data fetch completed after 3 seconds.
여기서는 느린 데이터 가져오기를 시뮬레이션하기 위해 인위적인 3초 지연을 추가했습니다. 그 결과 이제 데이터를 가져오는 동안 전체 페이지가 차단됩니다.
개발자가 해결해야 하는 공통 과제는 다음과 같습니다.
동적 렌더링을 사용하면 애플리케이션 속도는 가장 느린 데이터를 가져오는 속도만큼만 빨라집니다.