Development Environment#
- 상위 메뉴: Guides
- 전체 목차: Next.js 학습 문서
학습 목표#
next dev와 프로덕션 빌드의 컴파일 방식 차이를 설명한다.- 로컬 컴파일 지연을 파일 시스템, bundler, import, CSS, 데이터 요청 관점에서 점검한다.
- fetch 로그와 Turbopack trace로 느린 구간을 근거 있게 찾는다.
핵심 개념 및 설명#
앱이 커지면 로컬 컴파일 시간이 늘 수 있다. 무작정 설정을 바꾸기 전에 개발 모드가 어떤 작업을 하고 있는지 확인하고 병목을 재현한다.
로컬 개발과 프로덕션의 차이#
next dev는 방문하거나 이동한 route를 필요할 때 컴파일한다. 모든 route를 미리 만들지 않아 시작이 빠르고 메모리도 덜 쓴다. next build는 minify와 content hash 생성 같은 프로덕션 최적화까지 수행하므로 로컬 개발과 실행 시간 및 자원 사용량을 직접 비교하면 안 된다.
로컬 개발 성능 개선#
1. 컴퓨터의 백신 확인#
실시간 검사 도구가 소스 파일 읽기를 늦출 수 있다. Windows에서는 Microsoft Defender의 프로젝트 폴더 제외를 검토한다. macOS에서는 터미널에서 sudo spctl developer-mode enable-terminal을 실행한 뒤 시스템 설정의 개인정보 보호 및 보안 → 개발자 도구에서 사용하는 터미널을 허용하고 다시 시작한다. 다른 백신을 사용한다면 해당 제품의 설정도 확인하되 조직의 보안 정책을 먼저 따른다.


2. Next.js 업데이트와 Turbopack 사용#
최신 Next.js의 성능 개선을 확인한다. Turbopack은 개발 모드의 기본 bundler다. Webpack이 꼭 필요할 때만 pnpm dev --webpack을 사용한다.
pnpm add next@latest
pnpm dev # 기본값으로 Turbopack을 사용한다.
pnpm dev --webpack # Webpack이 필요할 때만 선택한다.3. import 확인#
큰 아이콘 패키지의 barrel export 대신 필요한 모듈을 직접 import한다. 여러 아이콘 세트를 함께 불러오지 말고 하나를 골라 사용한다. Dependency Cruiser나 Madge로 의존 관계를 살펴볼 수 있다.
// barrel export 대신 필요한 아이콘 파일을 직접 불러온다.
import { TriangleIcon } from '@phosphor-icons/react/dist/csr/Triangle'Webpack에서 barrel 파일이 큰 패키지는 experimental.optimizePackageImports를 검토한다. Turbopack은 import를 자동 분석하므로 이 설정이 필요 없다.
module.exports = {
experimental: {
optimizePackageImports: ['package-name'],
},
}4. Tailwind CSS 설정 확인#
content glob이 node_modules나 넓은 상위 디렉토리까지 훑지 않도록 실제 소스 범위로 좁힌다. Tailwind CSS 3.4.8 이상은 빌드를 느리게 할 수 있는 설정에 경고를 표시한다.
module.exports = {
content: [
'./src/**/*.{js,ts,jsx,tsx}',
// '../../packages/**/*.{js,ts,jsx,tsx}'처럼 node_modules까지
// 포함할 수 있는 넓은 범위는 피한다.
],
}5. 커스텀 Webpack 설정 확인#
개발 중에도 실행되는 plugin과 loader가 병목인지 확인한다. 필요하면 프로덕션에서만 켜거나 Turbopack loader로 옮긴다.
6. 메모리 사용량 최적화#
큰 앱은 Memory Usage의 heap 진단과 설정을 적용한다.
7. Server Component와 데이터 fetching#
Server Component 수정은 페이지 재렌더링과 데이터 재요청을 일으킨다. 실험 옵션인 serverComponentsHmrCache는 HMR 사이의 fetch 응답을 캐시해 개발 응답과 과금 API 호출을 줄일 수 있다.
8. Docker보다 로컬 개발 검토#
macOS와 Windows의 Docker bind mount는 HMR을 크게 늦출 수 있다. 가능하면 개발은 로컬에서 하고 Docker는 프로덕션 배포와 프로덕션 빌드 검사에 사용한다. Docker 개발이 꼭 필요하면 Linux 머신이나 VM을 검토한다.
문제를 찾는 도구#
상세 fetch 로깅#
개발 중 데이터 요청을 자세히 보려면 fetch 전체 URL 로그를 켠다.
module.exports = {
logging: {
fetches: {
fullUrl: true,
},
},
}Turbopack trace는 모듈별 컴파일 시간과 관계를 기록한다.
Turbopack tracing#
pnpm dev --internal-trace
# 느린 동작을 재현한 뒤 서버를 종료한다.
npx next internal trace .next-profiles/trace-turbopack.bintrace 명령이 없는 버전은 npx next internal turbo-trace-server .next-profiles/trace-turbopack.bin을 사용한다. trace viewer에서 집계 순서와 개별 span 순서를 바꿔 병목을 찾는다.
알아두면 좋은 점: trace 파일은 프로젝트 루트의 .next-profiles 디렉토리에 저장된다.여전히 문제가 있나요?#
해결하지 못한 문제를 보고할 때 trace 파일과 재현 절차를 GitHub Discussions나 Discord에 함께 제공한다.
예제 및 데모 설계#
- Phase 2에서 큰 barrel import와 직접 import의 첫 컴파일 시간을 비교한다.
- fetch 상세 로그로 HMR 전후의 Server Component 요청 횟수를 기록한다.
- Turbopack trace를 생성해 가장 오래 걸린 모듈과 의존 경로를 찾는다.
연습 문제#
next dev가 모든 route를 시작 전에 컴파일하지 않는 이유로 맞는 것은 무엇인가?
- 방문한 route를 필요할 때 컴파일해 시작 시간과 메모리를 줄이기 위해서다.
- 프로덕션 minify를 생략하지 않기 위해서다.
- content hash를 먼저 만들기 위해서다.
- E2E 테스트를 자동 실행하기 위해서다.
정답 보기
정답: 1. 개발 모드는 필요한 route를 지연 컴파일한다.
- Turbopack trace 파일이 기본 저장되는 곳은 어디인가?
public.next-profilesnode_modules/.cacheapp
정답 보기
정답: 2. 프로젝트 루트의 .next-profiles에 trace-turbopack.bin이 생성된다.
챕터 요약#
- 개발 모드는 방문한 route를 지연 컴파일하므로 프로덕션 빌드와 동작이 다르다.
- 파일 검사, bundler, import, Tailwind glob, 커스텀 Webpack 설정을 차례로 점검한다.
- Server Component HMR은 데이터 재요청까지 일으킬 수 있다.
- macOS와 Windows에서는 Docker 파일 시스템이 HMR 병목이 될 수 있다.
- fetch 로그와 Turbopack trace로 추측 대신 측정값을 남긴다.