멈추지 않는 기록

[Next.js] Next.js + Netlify에서 10MB GIF → 160KB MP4로 바꾸기 (feat. ffmpeg) 본문

개발/Next.js

[Next.js] Next.js + Netlify에서 10MB GIF → 160KB MP4로 바꾸기 (feat. ffmpeg)

pangil_kim 2025. 7. 25. 08:17
728x90
1. 문제 상황 소개

 

Next.js 기반의 개인 프로젝트에서 move.gif 애니메이션을 사용했다. 처음에는 잘 작동하는 듯했지만, Netlify에 배포하고 Lighthouse 성능 점수를 확인해보니 로딩 시간 지연과 성능 저하가 발생했다.

  • 용량: 10MB
  • 형식: .gif
  • 환경: Next.js 15 / Netlify / 정적 export
 특히 모바일 환경에서 느린 네트워크나 3G 조건으로 테스트할 경우, 사용자 경험에 큰 영향을 미칠 수 있었다.

 

 

2. 왜 GIF가 문제인가?

 

GIF는 기본적으로 프레임마다 전체 이미지를 렌더링하기 때문에 매우 비효율적이다. 단순한 애니메이션이라 하더라도 해상도가 높고 프레임 수가 많으면 용량이 폭발적으로 커진다.

포맷 장점 단점
GIF 간편, 모든 브라우저 호환 용량 큼, 압축 비효율적
MP4 고화질, 용량 작음, 빠른 로딩 <video> 태그 필요, 커스터마이징 필요
웹에서 GIF보다 훨씬 효율적인 대안이 바로 MP4, WebM, WebP 등 HTML5 기반 비디오 포맷이다.

 

 

3. 해결: ffmpeg로 변환

 

이를 해결하기 위해 ffmpeg를 활용하여 .gif.mp4 변환을 시도했다.

brew install ffmpeg     # (설치 안 돼 있다면)

ffmpeg -i move.gif -movflags faststart -pix_fmt yuv420p -vf "scale=500:-2" move.mp4

 

  • scale=500:-2: 가로폭 500px로 고정하고, 높이는 자동 계산하되 2의 배수로 맞춤
  • yuv420p: 대부분의 브라우저에서 색상 충돌 없이 재생 가능
  • faststart: MP4 헤더를 앞으로 이동시켜 빠른 시작 가능
.gif → .mp4 변환만으로도 용량은 수십 배 감소하고 UX는 월등히 개선된다.

 

 

4. Next.js에 적용하기

 

변환된 move.mp4/public/img에 넣고 아래처럼 <video> 태그로 적용했다:

<video autoPlay loop muted playsInline className="w-[500px] h-auto">
  <source src="/img/move.mp4" type="video/mp4" />
</video>
  • autoPlay, loop, muted: GIF처럼 자동 재생되고 반복되도록 설정
  • playsInline: iOS에서 전체화면으로 튀지 않고 인라인 재생 가능
React/Next 환경에서도 특별한 설정 없이 HTML5 video 태그로 손쉽게 사용할 수 있다.

 

 

5. 결과 비교 

 

단순히 포맷만 바꿨을 뿐인데도 놀라운 차이를 확인할 수 있었다.

항목
GIF MP4 변환 후
용량 10.2MB 164KB
로딩 시간 3.04초 983ms
브라우저 요청 200 OK 206 Partial ✅ (스트리밍 지원)
UX 느리고 튐 부드럽고 빠름 ✅

 

728x90