How to use and optimize videos

김동현·2026년 3월 5일

next.js 공식문서 번역

목록 보기
59/79

title: 비디오 사용 및 최적화 방법 (How to use and optimize videos)
description: Next.js 애플리케이션에서 비디오를 최적화하기 위한 권장 사항 및 모범 사례입니다.
url: "https://nextjs.org/docs/app/guides/videos"
version: 16.1.6
lastUpdated: 2026-02-27
prerequisites:


안녕하세요! 프론트엔드 개발의 세계에 오신 것을 환영합니다. 오늘은 웹사이트에 생동감을 불어넣어 주는 '비디오'를 Next.js에서 어떻게 다루고 최적화하는지 공식 문서를 통해 꼼꼼히 살펴볼 거예요.

이 페이지에서는 성능 저하 없이 비디오 파일을 저장하고 화면에 보여주는 방법 등, Next.js 애플리케이션에서 비디오를 사용하는 전반적인 방법을 설명해 줍니다. 잘 따라와 주세요!


<video><iframe> 사용하기

웹 페이지에 비디오를 삽입할 때는 크게 두 가지 방법을 써요. 비디오 파일을 직접 다룰 때는 HTML의 <video> 태그를 사용하고, 유튜브나 비메오 같은 외부 플랫폼에 호스팅된 비디오를 가져올 때는 <iframe> 태그를 사용한답니다.

<video>

HTML <video> 태그는 직접 호스팅하거나(self-hosted) 직접 제공되는 비디오 콘텐츠를 임베드할 수 있게 해줘요. 이 태그를 사용하면 비디오의 재생과 겉모습(UI)을 우리가 원하는 대로 완벽하게 제어할 수 있다는 장점이 있죠.

export function Video() {
  return (
    <video width="320" height="240" controls preload="none">
      <source src="/path/to/video.mp4" type="video/mp4" />
      <track
        src="/path/to/captions.vtt"
        kind="subtitles"
        srcLang="en"
        label="English"
      />
      Your browser does not support the video tag.
    </video>
  )
}

💡 강사 팁 & 보충 설명:
위 코드에서 preload="none" 속성이 보이시나요? 실무에서 아주 중요한 최적화 기법이에요! 사용자가 페이지에 들어오자마자 비디오를 재생할 확률이 낮다면, 굳이 처음부터 무거운 비디오 데이터를 미리 불러올(preload) 필요가 없겠죠? none으로 설정하면 초기 페이지 로딩 속도(LCP 등)를 확 끌어올릴 수 있고, 불필요한 네트워크 대역폭 낭비도 막을 수 있답니다.

자주 쓰이는 <video> 태그 속성들

속성 (Attribute)설명 (Description)예시 (Example Value)
src비디오 파일의 출처(경로)를 지정해요.<video src="/path/to/video.mp4" />
width비디오 플레이어의 너비를 설정해요.<video width="320" />
height비디오 플레이어의 높이를 설정해요.<video height="240" />
controls이 속성을 넣으면, 재생/일시정지 같은 기본 재생 컨트롤러가 화면에 나타나요.<video controls />
autoPlay페이지가 로드될 때 비디오를 자동으로 재생시켜요. (주의: 자동 재생 정책은 브라우저마다 조금씩 달라요!)<video autoPlay />
loop비디오 재생을 무한 반복시켜요.<video loop />
muted기본적으로 오디오를 음소거해요. 보통 autoPlay와 짝꿍으로 많이 쓰인답니다.<video muted />
preload비디오를 어떻게 미리 불러올지 지정해요. 값으로는 none(안 부름), metadata(길이 등 정보만 부름), auto(다 부름)가 있어요.<video preload="none" />
playsInlineiOS 기기에서 전체화면으로 넘어가지 않고 페이지 안에서(인라인으로) 재생되게 해줘요. iOS Safari에서 자동 재생이 되려면 이 속성이 필수인 경우가 많아요.<video playsInline />

알아두면 좋은 점 (Good to know): autoPlay 속성을 사용할 때는, muted 속성을 같이 넣어줘야 대부분의 브라우저에서 비디오가 차단되지 않고 자동으로 재생돼요. 그리고 iOS 기기와의 호환성을 위해 playsInline 속성도 꼭 챙겨주는 것이 중요합니다!

💡 강사 팁: 실무 면접에서도 종종 나오는 질문이에요. "모바일 사파리에서 비디오 자동 재생이 안 되는데 어떻게 해결하나요?" 정답은 바로 이 마법의 3콤보 autoPlay muted playsInline 이랍니다! 꼭 기억해 두세요.

비디오 속성에 대한 전체 목록이 궁금하다면 MDN 문서를 참고해 보세요.

비디오 모범 사례 (Best practices)

  • 대체 콘텐츠 (Fallback Content): <video> 태그를 사용할 때는, 구형 브라우저 등 비디오 재생을 지원하지 않는 환경을 대비해서 태그 안쪽에 대체 텍스트나 콘텐츠를 꼭 넣어주세요.
  • 자막 (Subtitles or Captions): 청각 장애가 있거나 소리를 듣기 어려운 환경에 있는 사용자를 위해 자막을 제공해 주세요. <video> 요소 안에 <track> 태그를 사용하면 자막 파일(vtt 등)의 경로를 지정할 수 있답니다. 웹 접근성(A11y) 측면에서 아주 훌륭한 습관이에요!
  • 접근성 있는 제어 (Accessible Controls): 키보드 탐색이나 스크린 리더와의 호환성을 위해서는 표준 HTML5 비디오 컨트롤을 사용하는 것을 권장해요. 만약 디자인적으로 더 복잡한 기능이나 커스텀이 필요하다면, 접근성 제어와 일관된 브라우저 경험을 제공해주는 react-playervideo.js 같은 서드파티 플레이어 라이브러리를 고려해 보는 것도 좋아요.

<iframe>

HTML <iframe> 태그를 사용하면 YouTube나 Vimeo 같은 외부 비디오 플랫폼의 동영상을 내 웹사이트에 쉽게 끼워 넣을 수 있어요.

export default function Page() {
  return (
    <iframe src="[https://www.youtube.com/embed/19g66ezsKAg](https://www.youtube.com/embed/19g66ezsKAg)" allowFullScreen />
  )
}

자주 쓰이는 <iframe> 태그 속성들

속성 (Attribute)설명 (Description)예시 (Example Value)
src임베드할 외부 페이지의 URL이에요.<iframe src="https://example.com" />
widthiframe의 너비를 설정해요.<iframe width="500" />
heightiframe의 높이를 설정해요.<iframe height="300" />
allowFullScreeniframe 콘텐츠가 전체 화면 모드로 표시될 수 있도록 허용해요.<iframe allowFullScreen />
sandboxiframe 내부 콘텐츠에 대해 보안 등의 이유로 추가적인 제한 사항을 설정해요.<iframe sandbox />
loading로딩 동작을 최적화해요 (예: 화면에 보일 때쯤 로드하는 지연 로딩 lazy).<iframe loading="lazy" />
title스크린 리더 등 웹 접근성을 지원하기 위해 iframe에 제목을 제공해요.<iframe title="Description" />

iframe 속성에 대한 전체 목록은 MDN 문서를 확인해 보세요.

비디오 임베딩 방식 선택하기

Next.js 애플리케이션에 비디오를 넣는 방식은 크게 두 가지로 나눌 수 있어요:

  • 직접 호스팅하거나 직접 비디오 파일 제공하기 (Self-hosted or direct video files): 플레이어의 기능과 디자인을 아주 디테일하게 제어해야 한다면 <video> 태그를 사용해 직접 호스팅한 비디오를 넣으세요. Next.js 내에서 이 방식을 쓰면 비디오 콘텐츠를 원하는 대로 커스터마이징하고 통제할 수 있습니다.
  • 비디오 호스팅 서비스 사용하기 (YouTube, Vimeo 등): 유튜브나 비메오 같은 서비스를 이용한다면, 그들이 제공하는 iframe 기반 플레이어를 <iframe> 태그로 임베드하게 됩니다. 이 방식은 플레이어 디자인이나 제어 권한이 조금 제한되긴 하지만, 연동이 매우 쉽고 해당 플랫폼이 제공하는 강력한 인프라(자동 화질 조절 등)를 거저 쓸 수 있다는 장점이 있죠.

여러분의 프로젝트 요구사항과 사용자에게 제공하고 싶은 경험이 무엇인지 잘 고민해 보고 딱 맞는 방식을 선택해 보세요!


외부 호스팅 비디오 임베딩하기 (React Suspense 활용)

외부 플랫폼에서 비디오를 가져와서 임베드할 때, Next.js의 서버 컴포넌트(Server Components) 기능을 이용해 비디오 정보를 먼저 가져오고, 로딩되는 동안에는 React Suspense를 활용해 임시 화면(Fallback)을 보여주는 우아한 처리 방식을 사용할 수 있어요.

1. 비디오 임베딩을 위한 서버 컴포넌트 만들기

첫 번째 단계는 비디오 임베딩에 필요한 적절한 iframe을 생성하는 서버 컴포넌트(Server Component)를 만드는 거예요. 이 컴포넌트는 비디오의 소스 URL을 비동기로(fetch) 가져온 다음 iframe을 렌더링하게 됩니다.

export default async function VideoComponent() {
  const src = await getVideoSrc()

  return <iframe src={src} allowFullScreen />
}

2. React Suspense를 사용해 비디오 컴포넌트 스트리밍하기

비디오를 임베드할 서버 컴포넌트를 만들었다면, 다음 단계는 React Suspense를 사용해서 그 컴포넌트를 스트리밍(stream) 하는 거예요.

import { Suspense } from 'react'
import VideoComponent from '../ui/VideoComponent.jsx'

export default function Page() {
  return (
    <section>
      <Suspense fallback={<p>비디오 로딩 중...</p>}>
        <VideoComponent />
      </Suspense>
      {/* 페이지의 다른 콘텐츠들 */}
    </section>
  )
}

💡 보충 설명: 왜 여기서 굳이 Suspense를 쓸까요? 외부 비디오 URL을 가져오는 비동기 작업(await getVideoSrc()) 때문에 전체 페이지의 렌더링이 멈춰버리면 안 되잖아요! Suspense를 쓰면 다른 부분은 먼저 화면에 쫙 보여주고(스트리밍), 비디오가 들어갈 자리만 "비디오 로딩 중..." 이라고 띄워둔 채 백그라운드에서 작업을 처리할 수 있어요. 사용자 경험(UX)이 엄청나게 좋아지는 마법이죠.

알아두면 좋은 점 (Good to know): 외부 플랫폼에서 비디오를 임베드할 때는 다음 모범 사례들을 꼭 고려해 보세요:

  • 비디오 임베드가 '반응형'으로 작동하는지 확인하세요. CSS를 잘 활용해서 화면 크기가 바뀌어도 iframe이나 비디오 플레이어의 비율이 깨지지 않게 만들어야 합니다. (보통 aspect-ratio CSS 속성을 많이 써요!)
  • 특히 데이터 요금제가 제한적인 모바일 사용자를 위해, 네트워크 상태에 따라 비디오를 효율적으로 로딩하는 전략을 구현해 보세요.

이러한 방식을 사용하면 비디오 컴포넌트가 로딩(스트리밍)되는 동안에도 페이지 전체가 멈추지(blocking) 않기 때문에 사용자는 페이지의 다른 부분과 계속 상호작용할 수 있어요. 결과적으로 훨씬 더 나은 사용자 경험을 제공하게 됩니다.

조금 더 세련되고 시각적으로 훌륭한 로딩 경험을 주고 싶다면, 단순한 텍스트 메시지 대신 '스켈레톤(Skeleton)' UI를 활용해 보세요. 실제 비디오 플레이어와 비슷한 윤곽선을 가진 컴포넌트를 만들어서 폴백(fallback)으로 넣어주는 거죠.

import { Suspense } from 'react'
import VideoComponent from '../ui/VideoComponent.jsx'
import VideoSkeleton from '../ui/VideoSkeleton.jsx'

export default function Page() {
  return (
    <section>
      <Suspense fallback={<VideoSkeleton />}>
        <VideoComponent />
      </Suspense>
      {/* 페이지의 다른 콘텐츠들 */}
    </section>
  )
}

직접 호스팅하는 비디오 (Self-hosted videos)

상황에 따라서는 유튜브나 비메오를 안 쓰고 비디오를 직접 서버에 올려서(Self-hosting) 서비스하는 게 더 좋을 때가 있어요. 이유를 살펴볼까요?

  • 완벽한 제어와 독립성: 비디오 콘텐츠, 재생 방식, 화면에 보이는 모습까지 모든 것을 직접 관리할 수 있어요. 외부 플랫폼의 정책이나 제약으로부터 완전히 자유로워지는 거죠.
  • 특정 요구사항에 맞춘 커스터마이징: 웹사이트 배경에 깔리는 다이나믹한 백그라운드 비디오처럼 독특한 기능이 필요할 때 아주 이상적이에요. 디자인과 기능적 요구에 맞게 마음껏 튜닝할 수 있으니까요.
  • 성능 및 확장성 고려: 사용자가 많아지고 콘텐츠 용량이 커져도 안정적으로 지원할 수 있도록 고성능이면서도 확장이 쉬운 스토리지(저장소) 솔루션을 선택할 수 있어요.
  • 비용 및 통합: 데이터 저장 비용과 네트워크 트래픽(대역폭) 비용, 그리고 Next.js 환경 및 기존 시스템들과 얼마나 쉽게 통합되는지 저울질해서 최적의 구성을 만들 수 있답니다.

Vercel Blob을 이용한 비디오 호스팅

Vercel Blob은 비디오를 효율적으로 호스팅할 수 있는 아주 좋은 방법이에요. Next.js와 찰떡궁합인 확장성 높은 클라우드 스토리지 솔루션이죠. Vercel Blob에 비디오를 호스팅하는 방법은 다음과 같습니다:

1. Vercel Blob에 비디오 업로드하기

Vercel 대시보드에서 "Storage" 탭으로 이동한 다음, 만들어 둔 Vercel Blob 스토어를 선택하세요. Blob 테이블의 우측 상단을 보면 "Upload" 버튼이 있을 거예요. 그걸 클릭하고 올리고 싶은 비디오 파일을 선택하면 됩니다. 업로드가 완료되면 목록(Blob table)에 비디오 파일이 나타납니다.

물론 대시보드에서 수동으로 안 하고, 코드로 처리할 수도 있어요. Server Action을 사용해서 비디오를 업로드할 수 있거든요. 자세한 방법은 Vercel의 서버 사이드 업로드 문서를 참고해 보세요. 브라우저에서 스토리지로 바로 쏘는 클라이언트 사이드 업로드도 지원한답니다. 특정 상황에서는 이 방식이 서버 부하를 줄여줘서 훨씬 유리할 수 있어요.

2. Next.js에서 비디오 보여주기

비디오 업로드와 저장이 끝났다면, 이제 Next.js 애플리케이션 화면에 띄워볼 차례입니다. <video> 태그와 React Suspense를 활용하는 예시 코드를 살펴볼게요:

import { Suspense } from 'react'
import { list } from '@vercel/blob'

export default function Page() {
  return (
    <Suspense fallback={<p>비디오 로딩 중...</p>}>
      <VideoComponent fileName="my-video.mp4" />
    </Suspense>
  )
}

async function VideoComponent({ fileName }) {
  const { blobs } = await list({
    prefix: fileName,
    limit: 1,
  })
  const { url } = blobs[0]

  return (
    <video controls preload="none" aria-label="Video player">
      <source src={url} type="video/mp4" />
      Your browser does not support the video tag.
    </video>
  )
}

이 접근 방식에서는 VideoComponent 안에서 Vercel Blob API를 사용해 비디오의 URL을 동적으로 가져와서 화면에 렌더링합니다. 그리고 URL을 가져오고 준비하는 비동기 시간 동안 빈 화면이 나오지 않게 하려고 React Suspense가 '비디오 로딩 중...' 이라는 폴백을 예쁘게 보여주는 거죠.

비디오에 자막 추가하기

비디오에 맞는 자막 파일(vtt 등)이 있다면, <video> 태그 안에 <track> 요소를 넣어서 아주 쉽게 추가할 수 있어요. 비디오 파일을 가져왔던 것처럼, Vercel Blob에서 자막 파일의 URL도 가져올 수 있죠. 자막을 포함하도록 아까 만든 <VideoComponent>를 이렇게 수정해 볼 수 있습니다.

async function VideoComponent({ fileName }) {
  const { blobs } = await list({
    prefix: fileName,
    limit: 2, // 파일 2개(비디오, 자막)를 찾습니다
  })
  const { url } = blobs[0]
  const { url: captionsUrl } = blobs[1]

  return (
    <video controls preload="none" aria-label="Video player">
      <source src={url} type="video/mp4" />
      <track src={captionsUrl} kind="subtitles" srcLang="en" label="English" />
      Your browser does not support the video tag.
    </video>
  )
}

이 흐름대로만 따라오시면 Next.js 애플리케이션에 우리가 직접 서버에 올린 비디오와 자막을 아주 근사하게 연동할 수 있답니다!


유용한 리소스들 (Resources)

비디오 최적화와 실무에서 쓰이는 모범 사례들을 더 깊이 파고들고 싶다면, 다음 자료들을 꼭 읽어보시길 권장해요. 개발자로서 큰 무기가 될 겁니다.

  • 비디오 포맷과 코덱 이해하기: 호환성을 최우선으로 한다면 MP4를, 웹 환경에서 용량 대비 화질(최적화)을 끌어올리고 싶다면 WebM 등 여러분의 필요에 맞는 올바른 포맷과 코덱을 선택해야 해요. 자세한 내용은 모질라(Mozilla)의 비디오 코덱 가이드를 참고해 보세요.
  • 비디오 압축 (Video compression): 화질은 최대한 유지하면서 파일 용량은 획기적으로 줄이려면 FFmpeg 같은 강력한 도구를 사용해 보세요. 압축 기술에 대해 궁금하다면 FFmpeg 공식 웹사이트에서 배울 수 있습니다.
  • 해상도와 비트레이트 조절: 모바일 기기 사용자에게는 굳이 4K 영상을 보낼 필요가 없겠죠? 시청하는 플랫폼과 환경에 맞춰 해상도와 비트레이트(Resolution and bitrate)를 조절하는 것이 성능의 핵심입니다.
  • 콘텐츠 전송 네트워크 (CDNs): 전 세계 어디서 접속하든 비디오를 빠르게 전송하고, 트래픽 폭주에 대비하려면 CDN을 꼭 활용해야 해요. Vercel Blob 같은 일부 클라우드 스토리지 솔루션을 쓰면 이런 CDN 기능이 알아서 척척 세팅된답니다. CDN과 그 엄청난 장점들에 대해 더 알아보세요.

Next.js 프로젝트에 비디오를 더욱 강력하게 연동하고 싶다면, 다음의 비디오 스트리밍 플랫폼 솔루션들도 눈여겨보세요:

오픈소스 next-video 컴포넌트

  • Next.js에 딱 맞는 <Video> 컴포넌트를 제공해요. Vercel Blob, AWS S3, Backblaze, Mux 등 다양한 호스팅 서비스와 완벽하게 호환됩니다.
  • 여러 호스팅 서비스와 next-video.dev를 연동하는 상세한 공식 문서가 아주 잘 되어 있어요.

Cloudinary 연동 (Cloudinary Integration)

Mux Video API

Fastly

  • 주문형 비디오(VOD)와 스트리밍 미디어를 Next.js에 통합하는 Fastly의 솔루션에 대해 자세히 알아보세요.

ImageKit.io 연동


모든 문서의 구조적(Semantic) 개요를 확인하려면, https://nextjs.org/docs/sitemap.md 를 참고해 주세요.

사용 가능한 모든 문서의 색인(Index)을 확인하려면, https://nextjs.org/docs/llms.txt 를 참고해 주세요.


수고하셨습니다! 혹시 이 번역본을 보시다가 이해가 안 가는 코드나, 본인의 프로젝트에 어떻게 적용해야 할지 막막한 부분이 있다면 언제든 편하게 질문해 주세요. 제가 도와드릴게요!

profile
프론트에_가까운_풀스택_개발자

0개의 댓글