| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- js
- linux
- 바이브코딩
- 5G에그
- 파일패킹
- 캐스팅연산자
- 게임제작
- VR
- VR플랫폼
- TCP
- 2D
- 게임개발
- Unity
- 메모리
- handtracking
- 유니티
- 클린 아키텍처
- 스펙주도형개발
- MacFilter
- PointableCanvasModule
- PHOTON
- 온라인
- C++
- C언어
- 게임은 문화
- DAIVerse
- 게임
- 캐시 메모리 사상
- OculusInteractionSamplesRayCanvas
- 동적 힙
- Today
- Total
kunyoungparkk
Next.js 요약 본문
Next.js에 대해 제대로 이해하고 활용하기 위해서,
인프런에서 이정환님의 한 입 크기로 잘라먹는 Next.js(v15)를 수강했습니다.
내용이 상당히 유익했고, 이를 통해 Next.js를 효과적으로 활용할 수 있을 것 같습니다.
몇가지 중요하다고 생각하는 부분을 간략하게만 정리해보고자 합니다.
Next.js란?
Next.js는 Vercel에서 개발한 오픈 소스 웹 개발 프레임워크로, React 기반 웹 애플리케이션에 서버 사이드 렌더링과 정적 렌더링을 제공합니다.
Next.js를 사용하는 이유?
React.js 앱의 기본적인 렌더링 방식은 클라이언트 사이드 렌더링입니다.
초기에 서버로 부터 빈 HTML 파일과 JS 번들을 전달받고, JS 파일을 실행하여 클라이언트 사이드에서 렌더링을 합니다.
이런 방식을 사용하기 때문에 초기 접속 이후의 페이지 이동이 매우 빠릅니다.
페이지 이동 시마다 서버에 다시 요청을 보내는 것이 아니라, JS를 내부적으로 실행만 하면 되기 때문입니다.
그러나, 초기에 렌더링을 클라이언트 브라우저에서 진행하기 때문에
사용자 입장에서 초기 접속 속도(FCP)가 느리다는 단점이 있습니다.
또한, 마운트 시점(useEffect)에 필요한 백엔드 서버로 HTTP 요청을 보내는 추가적인 데이터 로딩 시간이 발생합니다.
Next.js는 리액트의 장점인 초기 렌더링 이후의 빠른 페이지 이동을 계승하면서도,
위와 같은 React의 단점을 서버 사이드 렌더링과 여러 캐싱 방법을 통해 개선해줍니다.
먼저 서버에서 렌더링을 한 후에 렌더링 결과와 JS Bundle을 함께 클라이언트에 전달하여,
브라우저에서는 JS파일 실행 전에도 사용자에게 화면을 보여줄 수 있습니다.
이후에 브라우저 측에서도 JS 번들을 실행하여 렌더링 결과와 맞춰주는 수화(Hydration)의 과정을 거칩니다.

그러므로 이런 Next.js 활용의 핵심은 결국,
어떻게 Next.js에서 캐싱을 해두고 프로그래머는 이 기술들을 어떻게 잘 이용해서 사이트를 최적화할 것인가? 라고 할 수 있습니다.
이정환님의 강의의 핵심도 그런 부분이었습니다.
아래의 내용은, 최대한 간략히 핵심 개념 위주로 정리해보고자 합니다.
Next.js 핵심 개념
프리페칭
NextJS는 페이지별로 번들 코드를 별도로 저장해둡니다.
따라서, 페이지 이동시 번들 코드를 받아와야 합니다. (기존 React에선 없던 비효율)
이런 문제를 방지하기 위해 존재하는 기능이 프리페칭입니다.
: 현재 페이지에서 이동할 수 있는 연결된 모든 링크에 대한 JS를 미리 받아두는 것.
Link 태그로 연결된 애들만 프리패칭되고,
router.push(프로그래미틱한 방법)는 기본적으로 프리페칭이 안되지만, router.prefetch 함수를 통해 직접 프리페칭을 지정하면 됩니다.
사전 렌더링
- SSR: Server Side Rendering
말그대로 요청 들어오면 서버사이드에서 렌더링해서 주는 것
- SSG: Static Site Generation
빌드 타임에 정적 사이트 파일 미리 생성해둠.
- ISR : Incremental Static Regeneration
SSG를 주기적 혹은 트리거 발생(revalidate 함수)시 진행시키는 방법입니다.
App Router
기존 Page Router의 Navigating, Prefetching, 사전 렌더링을 유지하면서,
React 18(서버 컴포넌트), Layout, 데이터 패칭, 페이지 라우팅 시 다양한 설정 등이 추가된 새로운 Next.js.
React Server Component
React 18에서 추가된 새로운 유형의 컴포넌트로, 서버측에서만 실행됩니다.
백엔드 서버로부터 데이터를 패칭하는 등, 꼭 사용자 브라우저에서 하지 않아도 되는 동작(상호작용이 없는 동작)을 서버에서만 동작하게 할 수 있습니다.
서버에서 일괄적으로 처리하므로 이런 백엔드 서버로의 fetch들을 캐싱할 수 있는 강력한 장점이 있습니다.
Server Component는 서버 측의 사전렌더링 시에만 실행되고,
Client Component는 서버 측의 사전렌더링과 클라이언트 측의 수화 과정에서 총 2번 실행됩니다.
따라서 최대한 Server Component로 만드는 것이 관련된 최적화의 핵심입니다.
내부적으로 서버 컴포넌트의 하위에 클라이언트 컴포넌트가 배치되는 형태가 되며,
서버 컴포넌트에서 클라이언트 컴포넌트로 데이터를 전송하는 형태가 되기 때문에
서버 컴포넌트에서 클라이언트에서 보낼 수 있는 Props = 직렬화 가능한 Props 여야 합니다. (함수는 안됨)
이 직렬화된 데이터를 RSC Payload(React Server Component Payload)라고 하며, JS Bundle과 별도로 클라이언트에 전송됩니다.
정적 페이지와 동적 페이지
App router의 페이지 유형은 static page, dynamic page로 나뉩니다.
dynamic page란, 실시간성이 요구되는 페이지입니다. 캐시되지 않는 data fetching을 사용하거나, 쿼리/헤더/쿠키 등을 꺼내오는 동적함수를 사용하면 Next.js가 dynamic page로 자동 분류합니다. (dynamic option을 통해 수동 분류도 가능)
Next.js의 캐싱 방법

Full Route Cache
Build time에 페이지를 캐싱해두는 것입니다. 따라서, Static Page만 적용이 가능합니다.
쿼리 파라미터들을 캐싱해두면 dynamic page도 지정된 쿼리 파라미터에 대해서만 static page로 만들고 캐싱해둘 수 있습니다.
(generateStaticParams 함수 활용)
갱신 방법
- fetch api 사용 시, revalidate 옵션을 활용한 주기적 갱신
- revalidatePath 함수를 활용해 갱신 (캐시 제거)
Data Cache
fetch 함수의 cache 옵션을 통해, fetch 결과를 캐싱해둘 수 있습니다.
- "force-cache" : 요청결과 무조건 캐싱, 호출이후는 다시는 호출안됨.
- "no-store" : 페칭 결과 저장안함 (캐싱안함)
- {next:{revalidate: 3}} : 3초마다 캐시 갱신
- {next:{tags: ['a']}}: ?
Request Memoization
하나의 페이지를 렌더링하는 동안, API 요청 결과를 캐싱해둠.
따라서, 하나의 페이지 렌더링 중에, 동일한 API 요청은 한번만 실행됨.
Client Router Cache
브라우저에 저장되는 캐시로, 페이지의 일부 데이터를 보관합니다.
RSC Payload 중에, Layout에 대해 Client Router Cache에 보관하고,
이를 통해 페이지 이동을 더욱 효율적으로 진행할 수 있습니다.
기타
Suspense
- Suspense로 감싸면 사전 렌더링 때는 렌더링하지 않습니다. 정적 페이지에서 동적 함수(쿼리 스트링 갖고오기 등)를 활용할 때, 활용 가능합니다.
- 비동기 작업을 하는 컴포넌트를 감싸고, fallback 옵션을 통해 대체 UI 설정할 수 있습니다.
이외에도
간단하게 API 요청을 대체할 수 있는 서버 액션,
여러 페이지를 동시에 렌더링하는 병렬 라우트,
클라이언트 사이드의 페이지 이동을 차별화하는 인터셉트 라우트,
Loading.tsx을 활용한 스트리밍 구현,
병렬 라우트 시에 활용하는 Default.tsx,
에러 핸들링을 해주는 Error.tsx,
SEO,
Image 컴포넌트를 통한 최적화 등의 내용이 있었습니다.
느낀점
Next.js 프레임워크가 인기있는 이유를 체감할 수 있었습니다.
이 강의를 보기 전에는
서버 사이드 렌더링은 그저 서버에서 프론트엔드 렌더링을 해주니까 빠르다? 와 같이 추상적으로 이해하고 있었습니다.
Next.js의 핵심은 결국
서버에서 프론트엔드를 렌더링을 해주는 부분을 최대한 활용해서,
사용자인 개발자로 하여금 프론트엔드 내부 구조의 여러 구성요소를 쥐어짜내서,
최대한 최적화를 할 수 있게끔 강력한 캐싱 기능을 제공해준 것이라는 생각이 들었습니다.
상상 가능한, 프론트엔드 단에서의 최적화를 모두 구현해둔 프레임워크라는 생각이 들었고,
앞으로의 프론트엔드 개발 시에 이러한 최적화 방법론들을 최대한 활용해서 최적화된 프론트엔드를 구성하고자 합니다.