Next.js의 장점을 알아가자!
React는 순수하게 클라이언트(브라우저)에서 실행되는 UI 라이브러리인 반면, Next.js는 서버에서 코드를 실행할 수 있는 아키텍처를 제공하는 프레임워크다. 어떻게 Next.js는 단독으로 풀스택 개발이 가능할까?

Node.js 런타임을 활용한 서버 사이드 기능을 기본적으로 내장하고 있다. 서버 컴포넌트, 엔드포인트들은 브라우저가 아닌 Node.js 환경에서 실행된다.
Next.js의 App Router에서는 app 디렉터리를 root로 시작해서 디렉터리 중첩 구조대로 엔드포인트 url이 등록되기 때문에 별도 router 설정이 요구되지 않는다. 이는 개발 편의성 측면에서의 장점에도 속한다.
결과적으로 프론트엔드/백엔드 통합 개발로 생산성이 향상되며 환경 구성 시간이 단축되는 장점이 있다. API Routes를 통해 서버 로직을 구현할 수 있으므로 개발자에게는 JSP처럼 단일화된 개발 경험을 제공할 수 있다.

서버 사이드 렌더링의 목적은 최적의 렌더링 성능 및 SEO 확보다. 결과적으로는 사용자에게 화면을 빨리 보여주고, 인지도를 높이고, 재사용해서 웹사이트의 비즈니스적 가치를 높이는 것이다.
FCP 단축: 서버에서 미리 HTML을 만들어 제공하므로, 브라우저가 콘텐츠를 화면에 그리는 시간(First Contentful Paint)이 빨라져 사용자 경험이 향상된다.
Core Web Vitals 개선: 빠른 로딩 속도는 구글의 주요 사용자 경험 지표인 Core Web Vitals 점수를 높이는 데 직접적으로 기여하여 검색 순위 상승에 유리하다.
검색 엔진 크롤러는 JavaScript 실행 여부와 상관없이 HTML 파일만 열어봐도 페이지의 모든 정보(사용자가 보게 될 실제 텍스트, 이미지 경로, 링크 등의 모든 콘텐츠)를 즉시 파악할 수 있기 때문에 완벽한 HTML이다.
반면 CSR 렌더링을 수행하는 리액트는 서버에서 브라우저로 HTML을 처음 전송할 때 콘텐츠가 없는 빈 div와 js 파일 링크만 담고 있어서 페이지 정보 수집이 어렵다. 이 콘텐츠는 크롤러가 js를 실행해야만 비로소 보인다. (느리다)
SEO에서 유리한 고지를 선점하려면 크롤러가 내 웹사이트 페이지를 빨리 파악할 수 있게 해야 한다.
앞서 말한 app router의 파일 기반 라우팅이기 때문에 깔끔한 URL 구조는 SEO에 긍정적인 영향을 미친다.
메타데이터는 SEO 최적화에 중요한 역할을 한다. <Head> 컴포넌트로 페이지가 렌더링될 때마다 메타데이터 태그들을 동적으로 생성할 수 있다. 또한 구조화된 데이터도 서버에 쉽게 삽입하여 검색 엔진이 이 웹사이트를 더 잘 이해할 수 있도록 돕는다.
데이터베이스 연결 문자열, 써드파티 서비스의 Secret API Key, 서버 간 통신에 필요한 인증 토큰 등 외부에 노출되면 안 되는 민감한 정보는 오직 서버에서만 실행되는 코드 내에서 사용된다. 또한 페이지 렌더링하기 전에 서버 단에서 콘텐츠를 볼 수 있는 지 권한을 체크하여 리다이렉션 등을 할 수 있다.
Next.js: Webpack, Babel, TypeScript 설정이 모두 프레임워크에 내장되어 있어 개발자는 비즈니스 로직 개발에 집중할 수 있다.
React (수동 구성 시): 개발자가 직접 웹팩 설정을 구성하여 JavaScript 코드를 브라우저가 이해할 수 있도록 변환하고 번들링해야 한다. 시간이 소요된다.
Next.js: 각 페이지(라우트) 단위로 코드를 자동으로 분할(Split)하고, 사용자가 해당 페이지에 접근할 때 그 페이지에 필요한 JavaScript 코드만 다운로드한다.
Next.js의 이미지 최적화: next/image 컴포넌트를 사용하면 지연 로딩(Lazy Loading) 및 이미지 크기 최적화가 기본으로 적용된다.
React (수동 구성 시): React에서는 React.lazy()와 Suspense를 사용하여 수동으로 코드를 분할해야 하며, 이를 웹팩과 연동하는 설정이 필요하다.
Next.js
fetch API 캐싱과 요청 메모이제이션은 다른 맥락이다.
| 구분 | 요청 메모이제이션 (Request Memoization) | fetch API 캐싱 (Data Cache) |
|---|---|---|
| 작동 범위 | 단일 렌더링 요청 주기 (Single Request Lifetime) | 영구적인 캐시 저장소 (Persistence across requests) |
| 목적 | 중복 호출 방지 및 서버 왕복 횟수 감소 | 데이터 재사용 및 서버 부하 감소 |
| 저장 위치 | 메모리 (단일 요청이 끝날 때까지 유효) | Next.js 서버 캐시 (서버 디스크 또는 CDN) |
| 유효 기간 | 현재 HTTP 요청이 처리되는 동안만 유효함 | 재검증(Revalidation) 설정에 따라 무기한 또는 일정 시간 동안 유효함 |
| 비유 | 한 번의 함수 호출에서 동일 인수를 기억하는 memo() | 웹사이트의 콘텐츠를 일정 기간 저장하는 CDN 캐시 |
React
면접관이 Next.js의 장점을 묻는다면
캐싱을 못 말한게 아쉽네....