일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |
- 백준 2133
- 3XN 타일링
- 데이터 링크 계층
- 페이지교체알고리즘
- 13459
- 테스트주도개발
- stl
- ESP32
- 9996
- tfjs
- Vite 사용 이유
- 백준
- TDD
- 구현
- TDD란?
- mediastream
- 적두트리
- 메모리계층
- LOLIN D32
- RBT
- 1796
- 풀이
- 2623
- OpenVidu
- 자료구조
- REACT
- c++
- dp
- WebRTC란
- 구슬탈출
- Today
- Total
그냥 블로그
[Next.js] 정적 및 동적 렌더링 본문
https://nextjs.org/learn/dashboard-app/static-and-dynamic-rendering
정적 렌더링?
정적 렌더링을 사용하면 빌드 시(배포 시) 또는 재검증 중에 데이터 가져오기 및 렌더링이 서버에서 발생한다. 결과는 CDN(Content Delivery Network) 에 배포 및 캐시될 수 있습니다.
CDN(Content Delivery Network)
많은 장소에 걸쳐 분산된 서버들의 그룹. 서버들은 데이터의 중복 복사본들을 저장해 서버가 최종 사용자와 가장 가까운 서버를 기준으로 데이터 요청을 처리.
Bootstrap, jQuery 같은 라이브러리들의 스타일 시트 및 JavaScript 파일(정적 에셋)을 전송하는데 사용된다.
- CDN을 통해 라이브러리의 정적 애셋을 제공하면 라이브러리의 자체 서버 요청 부담이 줄어든다
- 대부분 CDN들은 전 세계에 서버를 갖고 있어 특정 라이브러리의 서버보다 사용자와 더 가까움.
- CDN들은 이미 적절한 캐시 설정이 되어 있어 CDN을 사용하면 자체 서버 정적 애셋을 위한 추가 설정이 필요 없다.
사용자가 애플리케이션을 방문할 때마다 캐시된 결과가 제공된다. 정적 렌더링에는 몇 가지 이점이 있다.
- 더 빠른 웹사이트 - 사전 렌더링된 콘텐츠를 캐시하고 전 세계적으로 배포 가능. 이를 통해 전 세계 사용자가 웹사이트 콘텐츠에 더욱 빠르고 안정적으로 엑세스 가능.
- 서버 로드 감소 - 콘텐츠가 캐시되기 때문에 서버는 각 사용자 요청에 대한 콘텐츠 동적 생성 필요 x
- SEO - 사전 렌더링된 콘텐츠는 페이지가 로드될 때 이미 콘텐츠를 사용할 수 있으므로 검색 엔진 크롤러가 색인 생성하기가 더 쉬움.
정적 렌더링은 정적 블로그 게시물이나 제품 페이지와 같이 사용자 간 공유되는 데이터나 데이터가 없는 UI에 유용하다.
동적 렌더링 ?
요청 시 (사용자가 페이지를 방문할 때) 각 사용자의 콘텐츠가 서버에서 렌더링됩니다.
- 실시간 데이터 - 동적 렌더링을 통해 애플리케이션은 실시간 또는 자주 업데이트되는 데이터를 표시할 수 있습니다. 이는 데이터가 자주 변경되는 애플리케이션에 이상적
- 사용자별 콘텐츠 - 대시보드나 사용자 프로필과 같은 개인화된 콘텐츠를 제공하고 사용자 상호 작용을 기반으로 데이터를 업데이트하는 것이 더 쉬움.
- 요청 시간 정보 - 동적 렌더링을 사용하면 쿠키나 URL 검색 매개변수와 같이 요청 시간에만 알 수 있는 정보에 엑세스할 수 있음.
unstable_noStore : 정적 렌더링 거부.
스트리밍?
느린 데이터로 사용자 경험 개선하기
경로를 더 작은 "청크"로 나누고 준비가 되면 서버에서 클라이언트로 점진적으로 스트리밍할 수 있는 데이터 전송 기
스트리밍하면 느린 데이터 요청이 전체 페이지를 차단하는 것 방지. 사용자는 UI가 사용자에게 표시되기 전 모든 ㅔ이터가 로드될 때까지 기다리지 않고 페이지 일부를 보고 상호 작용 가능.
Next.js에서 스트리밍 구현 방법
- 페이지 수준에서 loading.tsx 파일 사용
- 특정 구성 요소의 경우 <suspend>
loading.tsx
/app/dashboard에서 loading.tsx 새 파일 만들기.
- loading.tsx Suspense를 기반으로 페이지 콘텐츠가 로드되는 동안 대체 UI로 표시할 폴백 ui 생성가능하다.
- <SideNav>는 정적이므로 즉시 표현된다. 동적 콘텐츠가 로드되는 동안 상호 작용이 가능하다.
- 다른 페이지로 이동 전 페이지 로드가 완료될 때까지 기다릴 필요가 없다. ( 중단 가능 탐색 )
// /app/dashboard/loading.tsx
import DashboardSkeleton from '@/app/ui/skeletons';
export default function Loading() {
return <DashboardSkeleton />;
}
++ app 내 ()를 사용해 폴더를 생성하면 URL 경로에 포함되지 않는다. ex) (oveview)
구성요소 스트리밍 (React Suspense)
/app/dashboard/page.tsx
import CardWrapper from '@/app/ui/dashboard/cards';
// ...
import {
RevenueChartSkeleton,
LatestInvoicesSkeleton,
CardsSkeleton,
} from '@/app/ui/skeletons';
export default async function Page() {
return (
<main>
<h1 className={`${lusitana.className} mb-4 text-xl md:text-2xl`}>
Dashboard
</h1>
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
<Suspense fallback={<CardsSkeleton />}>
<CardWrapper />
</Suspense>
</div>
// ...
</main>
);
}
/app/ui/dashboard/cards.tsx
// ...
import { fetchCardData } from '@/app/lib/data';
// ...
export default async function CardWrapper() {
const {
numberOfInvoices,
numberOfCustomers,
totalPaidInvoices,
totalPendingInvoices,
} = await fetchCardData();
return (
<>
<Card title="Collected" value={totalPaidInvoices} type="collected" />
<Card title="Pending" value={totalPendingInvoices} type="pending" />
<Card title="Total Invoices" value={numberOfInvoices} type="invoices" />
<Card
title="Total Customers"
value={numberOfCustomers}
type="customers"
/>
</>
);
}
Suspense 경계를 배치할 위치 결정
Suspense 경계를 배치하는 위치는 다음 몇가지 사항을 고려
- 페이지가 스트리밍될 때 사용자가 페이지를 경험하기 원하는 방식
- 어떤 콘텐츠에 우선순위를 두고 싶은지
- 구성요소가 데이터 가져오기에 의존하는 경우
- 전체 페이지를 스트리밍하는 loading.tsx의 경우, 구성 요소 하나가 느려지면 전체 속도가 느려진다.
- 모든 구성 요소를 개별적으로 스트리밍할 수도 있지만 UI가 준비되면 화면에 갑자기 나타날 수 있다.
- 페이지 섹션을 스트리밍해 시차 효과를 만들 수 있다.
'프로젝트 > WALFI' 카테고리의 다른 글
메타 데이터 (0) | 2024.05.29 |
---|---|
[Next.js] (0) | 2024.05.24 |
[Next.js] app router + React Query (0) | 2024.05.20 |
[Next.js] Next.js 1 - 폴더 구조 (0) | 2024.05.10 |
[Web] WALFI Backend 연동 (JSP, MySQL) (0) | 2024.04.16 |