FE
[Next.js] Next.js + Netlify에서 10MB GIF → 160KB MP4로 바꾸기 (feat. ffmpeg)
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.mp4scale=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 | 느리고 튐 | 부드럽고 빠름 ✅ |