title: 서드파티 라이브러리 최적화 방법 (How to optimize third-party libraries)
description: "@next/third-parties 패키지를 사용하여 애플리케이션 내 서드파티 라이브러리의 성능을 최적화해보세요."
url: "https://nextjs.org/docs/app/guides/third-party-libraries"
version: 16.1.6
lastUpdated: 2026-02-27
prerequisites:
안녕하세요 여러분! 오늘은 프론트엔드 개발의 꽃이자 골칫거리이기도 한 서드파티(제3자) 라이브러리 최적화에 대해 Next.js 공식 문서를 함께 살펴보며 배워볼 거예요. 실무 팁도 팍팍 넣어드릴 테니 잘 따라와 주세요!
@next/third-parties는 Next.js 애플리케이션에서 우리가 자주 사용하는 인기 서드파티 라이브러리들을 불러올 때, 앱의 성능과 개발자 경험(DX)을 모두 끌어올려 주는 컴포넌트와 유틸리티 모음을 제공하는 라이브러리예요.
@next/third-parties에서 제공하는 모든 서드파티 통합 기능들은 성능과 사용 편의성을 극대화하도록 이미 최적화되어 있답니다.
💡 강사의 실무 팁: > 현업에서 서비스를 운영하다 보면 마케팅 팀이나 기획 팀에서 구글 애널리틱스(GA), 구글 태그 매니저(GTM), 채널톡 같은 외부 스크립트를 추가해 달라는 요청이 정말 많이 들어옵니다. 무턱대고 이걸 다
<head>에 넣었다가는 초기 로딩 속도(LCP)와 메인 스레드 차단 시간(TBT) 지표가 망가지기 십상이죠.이 패키지는 스크립트 실행 시점을 React 하이드레이션(Hydration) 이후로 영리하게 지연시켜서, 사용자가 화면을 빠르게 볼 수 있도록 보장해 주는 아주 고마운 도구입니다.
자, 먼저 @next/third-parties 라이브러리를 설치하면서 시작해 볼까요?
pnpm add @next/third-parties@latest next@latest
npm install @next/third-parties@latest next@latest
yarn add @next/third-parties@latest next@latest
bun add @next/third-parties@latest next@latest
@next/third-parties는 현재 활발하게 개발 중인 실험적인(experimental) 라이브러리예요. Next.js 팀에서 더 많은 서드파티 통합 기능을 추가하고 있기 때문에, 항상 latest(최신) 또는 canary(카나리) 플래그를 달아서 설치하시는 것을 권장해 드립니다.
구글에서 제공하는 모든 공식 지원 서드파티 라이브러리들은 @next/third-parties/google 경로를 통해 간편하게 불러올 수 있어요.
GoogleTagManager 컴포넌트는 여러분의 페이지에 구글 태그 매니저(Google Tag Manager) 컨테이너를 생성할 때 사용합니다. 기본적으로 이 컴포넌트는 페이지에서 React 하이드레이션이 일어난 이후에 원본 인라인 스크립트를 가져와서 실행해요.
👨🏫 보충 설명: 하이드레이션 이후에 불러온다는 건, 사용자가 웹사이트의 껍데기(HTML)를 다 보고 상호작용이 가능해진 시점 즈음에 무거운 마케팅 스크립트를 깐다는 뜻이에요. 사용자 경험을 절대 방해하지 않겠다는 Next.js의 의지죠!
모든 라우트(페이지)에 구글 태그 매니저를 적용하고 싶다면, 최상위 레이아웃(Root Layout) 파일에 컴포넌트를 직접 포함시키고 GTM 컨테이너 ID를 전달해주면 됩니다.
import { GoogleTagManager } from '@next/third-parties/google'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<GoogleTagManager gtmId="GTM-XYZ" />
<body>{children}</body>
</html>
)
}
import { GoogleTagManager } from '@next/third-parties/google'
export default function RootLayout({ children }) {
return (
<html lang="en">
<GoogleTagManager gtmId="GTM-XYZ" />
<body>{children}</body>
</html>
)
}
특정 단일 라우트에만 구글 태그 매니저를 로드하고 싶다면, 해당 페이지 파일에만 컴포넌트를 추가하세요:
import { GoogleTagManager } from '@next/third-parties/google'
export default function Page() {
return <GoogleTagManager gtmId="GTM-XYZ" />
}
sendGTMEvent 함수를 사용하면 dataLayer 객체를 통해 이벤트를 전송해서 사용자가 페이지에서 어떤 행동을 했는지 측정할 수 있어요. 이 함수가 제대로 작동하려면, <GoogleTagManager /> 컴포넌트가 부모 레이아웃, 부모 페이지/컴포넌트, 혹은 같은 파일 내에 반드시 포함되어 있어야 해요.
'use client'
import { sendGTMEvent } from '@next/third-parties/google'
export function EventButton() {
return (
<div>
<button
onClick={() => sendGTMEvent({ event: 'buttonClicked', value: 'xyz' })}
>
Send Event
</button>
</div>
)
}
어떤 변수와 이벤트를 함수에 전달할 수 있는지 더 자세히 알고 싶으시다면, 태그 매니저 개발자 문서를 참고해 보세요!
만약 서버사이드 태그 매니저를 사용 중이고 태깅 서버에서 직접 gtm.js 스크립트를 제공하고 있다면, gtmScriptUrl 옵션을 사용해서 해당 스크립트의 URL을 지정해줄 수 있습니다.
구글 태그 매니저에 전달할 수 있는 옵션들입니다. 전체 옵션 목록은 구글 태그 매니저 공식 문서에서 확인하실 수 있어요.
| 이름 (Name) | 타입 (Type) | 설명 (Description) |
|---|---|---|
gtmId | 필수(Required)* | GTM 컨테이너 ID입니다. 보통 GTM-으로 시작해요. |
gtmScriptUrl | 선택(Optional)* | GTM 스크립트 URL입니다. 기본값은 https://www.googletagmanager.com/gtm.js 예요. |
dataLayer | 선택(Optional) | 컨테이너를 초기화할 때 사용할 데이터 레이어 객체입니다. |
dataLayerName | 선택(Optional) | 데이터 레이어의 이름입니다. 기본값은 dataLayer 입니다. |
auth | 선택(Optional) | 환경 스니펫을 위한 인증 파라미터(gtm_auth) 값입니다. |
preview | 선택(Optional) | 환경 스니펫을 위한 미리보기 파라미터(gtm_preview) 값입니다. |
* gtmScriptUrl이 제공된 경우에는 광고주용 구글 태그 게이트웨이를 지원하기 위해 gtmId를 생략할 수 있습니다.
GoogleAnalytics 컴포넌트는 구글 태그(gtag.js)를 통해 페이지에 구글 애널리틱스 4(GA4)를 쉽게 추가할 수 있게 해 줍니다. 이 역시 기본적으로 페이지 하이드레이션 이후에 원본 스크립트를 가져와요.
💡 강력 추천 (Recommendation):
만약 여러분의 애플리케이션에 이미 구글 태그 매니저(GTM)가 추가되어 있다면, 구글 애널리틱스를 별도의 컴포넌트로 또 추가하지 마세요! 대신 GTM 내부에서 구글 애널리틱스를 설정하는 것을 권장합니다. 태그 매니저와gtag.js의 차이점에 대해 더 알고 싶으시면 공식 문서를 참고해 보세요. (강사 팁: 쓸데없이 스크립트를 중복으로 부르면 성능만 낭비됩니다!)
모든 페이지에서 구글 애널리틱스를 로드하려면, 최상위 레이아웃 파일에 컴포넌트를 넣고 측정 ID(Measurement ID)를 넘겨주세요:
import { GoogleAnalytics } from '@next/third-parties/google'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
<GoogleAnalytics gaId="G-XYZ" />
</html>
)
}
import { GoogleAnalytics } from '@next/third-parties/google'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
<GoogleAnalytics gaId="G-XYZ" />
</html>
)
}
단일 라우트에서만 로드하려면, 다음과 같이 해당 페이지 파일에만 추가하세요:
import { GoogleAnalytics } from '@next/third-parties/google'
export default function Page() {
return <GoogleAnalytics gaId="G-XYZ" />
}
sendGAEvent 함수를 사용하면 dataLayer 객체를 통해 이벤트를 전송해서 페이지 내 사용자의 행동을 측정할 수 있어요. GTM 때와 마찬가지로, 이 함수가 작동하려면 <GoogleAnalytics /> 컴포넌트가 부모 레이아웃/페이지나 같은 파일에 반드시 존재해야 합니다.
'use client'
import { sendGAEvent } from '@next/third-parties/google'
export function EventButton() {
return (
<div>
<button
onClick={() => sendGAEvent('event', 'buttonClicked', { value: 'xyz' })}
>
Send Event
</button>
</div>
)
}
이벤트 파라미터에 대한 자세한 내용은 구글 애널리틱스 개발자 문서에서 확인할 수 있습니다.
구글 애널리틱스는 브라우저의 히스토리 상태(History state)가 변경될 때 자동으로 페이지뷰를 추적합니다. 즉, Next.js 라우트 간의 클라이언트 사이드 네비게이션(Client-side navigation)이 일어날 때 아무런 추가 설정 없이도 페이지뷰 데이터가 잘 전송된다는 뜻이에요! (React SPA의 큰 장점이죠.)
클라이언트 사이드 네비게이션이 정확하게 측정되고 있는지 확실히 하려면, GA 관리자 패널에서 “향상된 측정 (Enhanced Measurement)” 속성이 켜져 있고, "브라우저 기록 이벤트에 기반한 페이지 변경 (Page changes based on browser history events)" 체크박스가 선택되어 있는지 꼭 확인하세요.
주의 (Note): 만약 페이지뷰 이벤트를 '수동'으로 전송하기로 결정했다면, 데이터가 중복으로 쌓이지 않도록 기본 페이지뷰 측정 기능은 반드시 꺼주세요. 더 자세한 내용은 구글 애널리틱스 개발자 문서를 참고하시면 됩니다.
<GoogleAnalytics> 컴포넌트에 넘겨줄 수 있는 옵션들입니다.
| 이름 (Name) | 타입 (Type) | 설명 (Description) |
|---|---|---|
gaId | 필수(Required) | 여러분의 측정 ID 입니다. 보통 G-로 시작해요. |
dataLayerName | 선택(Optional) | 데이터 레이어의 이름입니다. 기본값은 dataLayer 예요. |
nonce | 선택(Optional) | 암호화 논스(nonce) 값입니다. 보안 정책을 위해 쓰이죠. (관련 가이드) |
GoogleMapsEmbed 컴포넌트를 사용하면 페이지에 구글 지도 임베드(Google Maps Embed)를 손쉽게 추가할 수 있습니다.
기본적으로 이 컴포넌트는 loading 속성을 사용해서 화면의 스크롤을 내려야 보이는 영역(below the fold)에 지도가 있을 때, 지연 로딩(lazy-load)을 수행해요.
💡 강사의 실무 팁: > 지도를 로드하는 건 네트워크 자원을 꽤 많이 소모합니다. 처음에 화면에 보이지도 않는 지도를 미리 다운로드하느라 정작 중요한 콘텐츠가 늦게 뜨면 안 되겠죠? 이 컴포넌트는 알아서 화면에 보일 때쯤 지도를 불러와 줘서 성능 관리에 아주 유용합니다!
import { GoogleMapsEmbed } from '@next/third-parties/google'
export default function Page() {
return (
<GoogleMapsEmbed
apiKey="XYZ"
height={200}
width="100%"
mode="place"
q="Brooklyn+Bridge,New+York,NY"
/>
)
}
구글 지도 임베드에 넘길 수 있는 옵션입니다. 전체 옵션 목록은 구글 지도 임베드 문서를 읽어보세요.
| 이름 (Name) | 타입 (Type) | 설명 (Description) |
|---|---|---|
apiKey | 필수(Required) | 발급받은 API 키를 넣으세요. |
mode | 필수(Required) | 지도 모드 (Map mode)를 설정합니다. |
height | 선택(Optional) | 임베드의 높이입니다. 기본값은 auto 예요. |
width | 선택(Optional) | 임베드의 너비입니다. 기본값은 auto 예요. |
style | 선택(Optional) | iframe에 직접 스타일을 적용할 때 사용합니다. |
allowfullscreen | 선택(Optional) | 지도의 특정 부분을 전체화면으로 볼 수 있도록 허용하는 속성입니다. |
loading | 선택(Optional) | 기본값은 lazy(지연 로딩)입니다. 만약 지도가 스크롤 없이 처음부터 바로 보이는 최상단 영역(above the fold)에 있다면 속성을 변경하는 것을 고려하세요. |
q | 선택(Optional) | 지도 마커의 위치를 정의합니다. 지도 모드에 따라 이 옵션이 필수일 수도 있어요. |
center | 선택(Optional) | 지도 뷰의 중심 좌표를 정의합니다. |
zoom | 선택(Optional) | 지도의 초기 확대/축소(Zoom) 레벨을 설정합니다. |
maptype | 선택(Optional) | 로드할 지도 타일의 종류(예: 위성, 지형 등)를 정의합니다. |
language | 선택(Optional) | UI 요소 및 지도 타일 위 라벨을 표시할 때 사용할 언어를 정의합니다. |
region | 선택(Optional) | 지정학적 민감도에 따라 표시할 적절한 국경선과 라벨을 정의합니다. |
YouTubeEmbed 컴포넌트는 유튜브 영상을 임베드하고 보여줄 때 사용합니다. 이 컴포넌트가 아주 똑똑한 이유는, 내부적으로 lite-youtube-embed라는 라이브러리를 사용해서 기존 방식보다 훨씬 빠르게 로드되기 때문이에요!
💡 강사의 실무 팁: >
일반적인 유튜브iframe을 그대로 넣으면 썸네일 하나 띄우려고 엄청난 양의 자바스크립트를 다운로드합니다. 하지만lite-youtube-embed를 사용하면 가짜(?) 썸네일 이미지(Facade 패턴)를 먼저 보여주고, 사용자가 실제로 재생 버튼을 눌렀을 때만 진짜 유튜브 플레이어를 로딩해요. 사이트 로딩 속도가 획기적으로 개선됩니다!
import { YouTubeEmbed } from '@next/third-parties/google'
export default function Page() {
return <YouTubeEmbed videoid="ogfYd705cRs" height={400} params="controls=0" />
}
| 이름 (Name) | 타입 (Type) | 설명 (Description) |
|---|---|---|
videoid | 필수(Required) | 유튜브 비디오 ID 입니다. (주소창의 v= 다음 부분) |
width | 선택(Optional) | 비디오 컨테이너의 너비입니다. 기본값은 auto 예요. |
height | 선택(Optional) | 비디오 컨테이너의 높이입니다. 기본값은 auto 예요. |
playlabel | 선택(Optional) | 웹 접근성(A11y)을 위해 화면에는 보이지 않지만 스크린리더가 읽을 수 있는 재생 버튼 라벨입니다. |
params | 선택(Optional) | 여기에 정의된 비디오 플레이어 파라미터들입니다. 파라미터들은 쿼리 스트링 형태로 전달됩니다. 예: params="controls=0&start=10&end=30" |
style | 선택(Optional) | 비디오 컨테이너에 직접 스타일을 적용할 때 사용합니다. |
이외의 전체 문서의 구조와 흐름을 시맨틱하게 파악하려면 https://nextjs.org/docs/sitemap.md 를 참고하세요.
이용 가능한 모든 문서의 색인(Index)을 확인하고 싶다면 https://nextjs.org/docs/llms.txt 를 살펴보시면 됩니다.