Next.js를 사용하면서 많은 사람들이 자연스럽게 선택하는 컴포넌트가 있습니다. 바로 next/image입니다.
이미지 관리를 자동화해주고 성능 최적화까지 해주니, 정말 매력적인 기능이죠.
하지만 실제 운영 환경에서는 이 next/image가 예상치 못한 문제를 일으킬 수도 있습니다.
특히 optimize: true 설정을 사용할 때 주의해야 할 점들이 있었습니다.
오늘은 제가 이 문제를 고민했던 경험을 바탕으로, 왜 next/image를 쓰는지, 그리고 optimize 설정을 현명하게 다루는 방법까지 정리해보려고 합니다.
왜 next/image를 사용하는가?
먼저, next/image가 제공하는 장점은 정말 강력합니다.
- 자동 최적화 (Optimization)
요청하는 디바이스에 맞게 이미지를 리사이즈하거나, WebP, AVIF 같은 최신 포맷으로 변환하여 최적화된 이미지를 전송해줍니다. 결과적으로 페이지 로딩 속도가 크게 향상됩니다. - 지연 로딩 (Lazy Loading)
사용자가 화면에 스크롤하기 전까지 이미지를 로딩하지 않습니다. 이로 인해 초기 로딩이 가벼워지고, LCP(Largest Contentful Paint) 같은 웹 퍼포먼스 지표도 좋아집니다. - Placeholder 지원 (Blur-up)
이미지를 로딩하는 동안 흐릿한 미리보기 이미지를 제공하여, 사용자 경험(UX)을 부드럽게 만듭니다. - Responsive srcset 자동 생성
다양한 디바이스 해상도에 맞게 자동으로 srcset을 생성합니다. 고해상도 디스플레이(iPhone, 4K 모니터 등)에서도 선명한 이미지를 제공할 수 있습니다. - 레이아웃 안정성 확보
height와 width를 명시적으로 지정하게 함으로써 레이아웃 시프트(CLS)를 방지합니다.
이 모든 기능을 별도 설정 없이, 단순히 next/image를 사용하기만 하면 얻을 수 있다는 점은 정말 매력적이었습니다.
optimize: true의 그림자
하지만 optimize: true 설정을 켜고 운영해보면서 몇 가지 중요한 문제를 발견했습니다.
next/image는 optimize가 활성화되었을 때, 서버에서 다음 작업을 수행합니다.
- 원본 이미지를 메모리에 올림
- 리사이징
- 포맷 변환 (WebP, AVIF 등)
- 압축(quality 조정)
이 과정은 CPU와 메모리 자원을 상당히 많이 소모합니다. 특히 다음과 같은 상황에서는 위험이 커집니다.
- 고해상도 원본 이미지를 처리할 때
- 동시에 많은 이미지 최적화 요청이 들어올 때
- 서버 메모리가 충분하지 않은 경우
이미지 한 장 최적화에 5~10배의 메모리 사용이 발생할 수 있고, 이게 겹치면 서버 메모리가 터지면서 OOM(Out of Memory) 크래시가 발생할 수 있습니다.
실제로 대규모 트래픽을 처리하는 서비스나, 이미지가 많은 서비스에서는 optimize가 켜진 상태로 서버를 운영하면 메모리 부족 문제를 경험하는 경우가 적지 않습니다.
그렇다면 어떻게 해야 할까?
저는 다음과 같은 방향으로 해결책을 고민했습니다.
1. 외부 이미지 최적화 서비스 사용
next/image는 자체 최적화(optimize)를 끄고(optimize: false) 대신 외부 최적화 서비스를 연결할 수 있습니다.
대표적으로:
- Vercel의 Image Optimization
- Cloudflare Images
- Imgix
- ImageKit
이런 서비스는 고성능으로 이미지 최적화를 해주고, 글로벌 CDN에 캐싱까지 해주기 때문에 서버 부하를 거의 0에 가깝게 만들 수 있습니다.
// next.config.js
module.exports = {
images: {
loader: 'imgix', // 또는 'cloudinary', 'custom' 등
path: 'https://your-image-service.com/',
},
};
이렇게 설정하면 Next.js 서버는 최적화 작업을 하지 않고, 외부 서비스를 통해 최적화된 이미지를 바로 서빙합니다.
2. 서버 메모리 확장
가장 단순한 방법은 서버 사양을 올리는 것입니다. 메모리와 CPU를 확장하면 어느 정도 최적화 부하를 견딜 수 있습니다.
하지만 이 방법은 비용이 기하급수적으로 증가할 수 있어 장기적인 해결책으로는 추천하지 않습니다.
3. 이미지 사전 최적화 (Preprocessing)
빌드 시점이나 업로드 시점에 미리 이미지를 최적화해두고, 운영 서버에서는 가공 없이 바로 서빙하는 방법입니다.
예를 들면, CMS에 이미지를 업로드할 때 sharp 같은 라이브러리로 미리 리사이징/압축을 걸어두는 식입니다.
결론
next/image는 현대 프론트엔드 개발자에게 정말 강력한 도구입니다.
특히 자동 최적화 기능(optimize)은 페이지 속도 개선과 사용자 경험 향상에 큰 도움이 됩니다.
하지만,
optimize: true는 서버에 적지 않은 부담을 준다는 것을 반드시 기억해야 합니다.
- 작은 프로젝트, 저트래픽 서비스 → 그냥 optimize를 켜고 쓰는 것도 OK
- 중대형 서비스, 고트래픽 사이트 → optimize를 끄고 외부 이미지 최적화 서비스를 고려해야 합니다.
'software engineering > frontend' 카테고리의 다른 글
Apollo Client Refetch 구조 개선하기: SSE 알림과 Error 핸들링까지 (0) | 2025.04.28 |
---|---|
퍼포먼스 최적화(Next.js App Router) (0) | 2025.04.28 |
실시간 데이터 갱신을 위한 SSE(Server-Sent Events)와 WebWorker 활용기 (0) | 2025.04.28 |
JSON-Patch: 대규모 JSON 관리를 위한 효율적인 도구 (0) | 2025.01.22 |
KeycloakJs를 이용한 다중 계정 전환 Web Component개발기 (1) | 2025.01.22 |