Next.js14로 블로그 만들기를 진행 중인데... 블로그 리스트를 보여주는 첫 메인 화면에서 문제가 발생했다.
분명 DB를 제대로 바라보고 있음에도 불구하고 로컬 환경에선 새로운 글을 쓰면 blogList API가 새로운 글을 바로 추가해서 같이 보여주는데, 배포 환경에선 blogList API에 새로운 글이 보이지 않았다.
API에서 ORM으로 잘못 불러오고 있나..? 라기엔 로컬에서 너무 잘불러옴^-^
고구마 천백만 개 먹고 있을 때 쯤 구글링을 해보다가 스택오버플로우에서 비슷한 증상 확인 후에 적용해보니 해결됐다... 황당
근데 저게 대체 뭔데..? 정적, 동적 렌더링... 알아보자!
Next.js app route page에서 data fetching 시 별도로 캐시 설정을 하지 않더라도 기본적으로 캐시를 사용한다.
이를 통해 불필요한 데이터 패칭을 하지 않아도 되며, 서버는 이미 만들어진 파일들을 사용자에게 응답하기만 하면 되기 때문에 유저는 더 빠른 응답 속도를 기대할 수 있다.
Next.js 12의 page 디렉토리의 경우 getStaticProps
를 사용하여 빌드 타임에 정적 파일들을 생성했으나, app 디렉토리에서는 특수 함수를 사용하지 않고 서버 컴포넌트 내부에서 간단하게 api를 호출하기만 해도 동작한다.
따라서 Next.js app 디렉토리의 페이지는 기본적으로 dynamic function을 사용하지 않는다면 static rendering을 채택한다.
정적 렌더링을 사용하면 빌드 시간 (배포할 때) 또는 재검증 중에 서버에서 데이터를 가져오거나 렌더링이 이루어진다.
그 후에 해당 결과를 CDN에 배포하고 캐시할 수 있다.
사용자가 애플리케이션을 방문할 때마다 캐시된 결과가 제공된다. 정적 렌더링은 몇 가지 장점이 있다.
정적 렌더링은 정적 블로그 게시물이나 제품 페이지와 같이 데이터가 없거나 사용가 잔에 공유되는 데이터가 없는 UI에 유용하다. 정기적으로 업데이트되는 개인화된 데이터가 있는 대시보드에는 적합하지 않을 수 있다.
동적 렌더링을 사용하면 요청 시 (사용자가 페이지를 방문할 때) 각 사용자의 컨텐츠가 서버에서 렌더링된다.
기본적으로 @vercel/postgres
는 자체 캐싱 시멘틱을 설정하지 않는다. 따라서 프레임워크가 자체 정적 및 동적 동작을 설정할 수 있다.
서버 컴포넌트 또는 데이터 불러오기 함수 내에서 unstable_noStore
라는 Next.js API를 사용하여 정적 렌더링을 사용하지 않도록 선택할 수 있다.
import { unstable_noStore as noStore } from 'next/cache';
export async function fetchRevenue() {
// Add noStore() here to prevent the response from being cached.
// This is equivalent to in fetch(..., {cache: 'no-store'}).
noStore();
}
unstable_noStore
는 실험적인 API이며, 향후 변경될 수 있다. 프로젝트에서 안정적인 API를 사용하려는 경우 세그먼트 구성 옵션export const dynamic = 'force-dynamic'
을 사용할 수도 있다.
동적 렌더링으로 설정할 경우, 데이터를 가져오는 동안 전체 페이지가 차단된다.
즉, 동적 렌더링을 사용하면 애플리케이션의 속도가 가장 느린 데이터를 가져오는 속도만큼만 빨라진다.
이러한 문제점은 streaming을 통해 해결할 수 있다.
streaming은 경로를 더 작은 'chunks'로 나누고 준비되는 대로 서버에서 클라이언트로 점진적으로 스트리밍할 수 있는 데이터 전송 기술이다.
streaming을 사용하면 느린 데이터 요청이 전체 페이지를 차단하는 것을 방지할 수 있다. 이를 통해 사용자는 UI가 사용자에게 표시되기 전에 모든 데이터가 로드될 때까지 기다리지 않고 페이지의 일부를 보고 상호 작용할 수 있다.
<Suspense>
사용하기/app/dashboard/
폴더에서 loading.tsx
파일을 만든다.
// /app/dashboard/loading.tsx
export default function Loading() {
return <div>Loading...</div>;
}
loading.tsx
는 Suspense
위에 구축된 특별한 Next.js 파일로, 페이지 컨텐츠가 로드되는 동안 대체로 표시할 폴백 UI를 만들 수 있다.Suspense를 사용하면 일부 조건이 충족될 때까지 애플리케이션의 렌더링 부분을 연기할 수 있다. Suspense에서 동적 컴포넌트를 래핑할 수 있다. 그런 다음 동적 컴포넌트가 로드되는 동안 표시할 대체 컴포넌트를 전달한다.
// /app/dashboard/page.tsx
import { Suspense } from 'react';
import { RevenueChartSkeleton } from '@/app/ui/skeletons';
export default async function Page() {
return (
<Suspense fallback={<RevenueChartSkeleton />}>
<RevenueChart />
</Suspense>
);
}
// /app/ui/dashboard/revenue-chart.tsx
import { fetchRevenue } from '@/app/lib/data';
export default async function RevenueChart() {
const revenue = await fetchRevenu();
...
}
< 참고 : https://nextjs.org/learn/dashboard-app/static-and-dynamic-rendering
https://nextjs.org/learn/dashboard-app/streaming
https://velog.io/@jay/Next.js-13-master-course-Static-Dynamic-Rendering >