Next.js의 Script 컴포넌트 (next/script
)는 웹 애플리케이션의 어디에서나 최적의 성능으로 서드파티 스크립트를 로드할 수 있도록 해줍니다. HTML의 <script>
요소의 확장 기능이며, 사용 사례에 맞는 다양한 로딩 전략 중에서 선택할 수 있도록 제공합니다.
웹 사이트는 분석, 광고, 고객 지원 위젯 및 동의 관리와 같은 기능을 추가하기 위해 종종 서드파티 스크립트를 사용합니다. 그러나 이렇게 하면 사용자 경험과 개발자 경험 모두에 영향을 미치는 문제가 발생할 수 있습니다.
브라우저는 HTML의 위치 및 async
와 defer
속성의 사용에 따라 <script>
요소를 로드하고 실행합니다. 그러나 기본 <script>
요소를 사용하면 다음과 같은 문제점이 발생합니다.
<script>
속성 (예: defer
)은 추가 작업 없이는 호환되지 않습니다.Script
컴포넌트는 타사 스크립트를 로드하기 위한 선언적 API를 제공하여 이러한 문제를 해결합니다. 스트리밍을 지원하여 스크립트 로딩 순서를 최적화하기 위한 내장 로딩 전략 세트를 제공합니다. Script
컴포넌트가 제공하는 각 전략은 React 및 Web API
의 최상의 조합을 사용하여 스크립트가 페이지 성능에 미치는 영향을 최소화합니다.
시작하려면 next/script
컴포넌트를 가져와서 다음과 같이 import합니다:
import Script from 'next/script'
단일 경로에서 서드파티 스크립트를 로드하려면 next/script
를 가져와서 페이지 컴포넌트에 직접 스크립트를 포함합니다:
import Script from 'next/script';
export default function Dashboard() {
return (
<>
<Script src='https://example.com/script.js' />
</>
);
}
이 스크립트는 브라우저에서 이 특정 페이지가 로드될 때만 가져와 실행됩니다.
모든 경로에 대해 서드파티 스크립트를 로드하려면 next/script
를 가져와서 pages/\_app.js
에 직접 스크립트를 포함합니다:
import Script from 'next/script';
export default function MyApp({ Component, pageProps }) {
return (
<>
<Script src='https://example.com/script.js' />
<Component {...pageProps} />
</>
);
}
이 스크립트는 응용 프로그램에서 어떤 경로가 액세스되더라도 로드되고 실행됩니다. Next.js
는 사용자가 여러 페이지를 탐색하더라도 스크립트가 한 번만 로드되도록 보장합니다.
참고: 응용 프로그램의 모든 페이지에서 서드파티 스크립트를 로드해야 할 필요성은 거의 없습니다. 불필요한 성능 영향을 최소화하기 위해 특정 페이지에만 서드파티 스크립트를 포함하는 것이 좋습니다.
next/script
의 기본 동작은 모든 페이지에서 서드파티 스크립트를 로드할 수 있도록 하지만, strategy 속성을 사용하여 로드 동작을 조정할 수 있습니다:
beforeInteractive
: Next.js 코드와 페이지 하이드레이션 이전에 스크립트를 로드합니다.afterInteractive
: (기본값) 페이지 하이드레이션 후 일부로딩이 완료된 후 스크립트를 로드합니다.lazyOnload
: 브라우저가 유휴 상태 일 때 스크립트를 나중에 로드합니다.worker
: (실험적) 웹 워커에서 스크립트를 로드합니다.참고: 브라우저에서
next/script
컴포넌트가 로드된 이후에는 이 컴포넌트가 DOM에 남아 있으므로 클라이언트 측 네비게이션으로 스크립트를 다시 실행하지 않습니다.
참고: worker
전략은 아직 안정화되지 않았으며 app/
디렉토리에서 작동하지 않습니다. 주의해서 사용하세요.
worker
전략을 사용하는 스크립트는 Partytown
으로 웹 워커에서 로드되고 실행됩니다. 이를 통해 주 스레드를 응용 프로그램 코드의 나머지에 전념하여 성능을 개선할 수 있습니다.
이 전략은 아직 실험적이며, next.config.js
에서 nextScriptWorkers
플래그를 사용하여만 사용할 수 있습니다:
module.exports = {
experimental: {
nextScriptWorkers: true,
},
}
그런 다음 next
(보통 npm run dev
또는 yarn dev
)을 실행하면 Next.js
가 필요한 패키지를 설치하기 위한 안내를 제공합니다:
npm run dev
# 이와 같은 지침이 표시됩니다.
#
# Please install Partytown by running:
#
# npm install @builder.io/partytown
#
# ...
설치가 완료되면 strategy="worker"
를 정의하면 자동으로 Partytown
이 애플리케이션에 인스턴스화되고 스크립트가 웹 워커로 오프로드됩니다.
import Script from 'next/script'
export default function Home() {
return (
<>
<Script src="https://example.com/script.js" strategy="worker" />
</>
)
}
웹 워커에서 타사 스크립트를 로드할 때 고려해야 할 상당수의 트레이드오프가 있습니다. 자세한 내용은 Partytown
의 트레이드오프 문서를 참조하세요.
외부 파일에서 로드되지 않는 인라인 스크립트는 Script
컴포넌트에서도 지원됩니다. 자바스크립트를 중괄호로 묶어 작성하면 됩니다:
<Script id='show-banner' strategy='afterInteractive'>
{`document.getElementById('banner').classList.remove('hidden')`}
</Script>
dangerouslySetInnerHTML
속성을 사용하여 작성할 수도 있습니다:
<Script
id='show-banner'
strategy='afterInteractive'
dangerouslySetInnerHTML={{
__html: `document.getElementById('banner').classList.remove('hidden')`,
}}
/>
참고: 인라인 스크립트에는 추적 및 최적화하기 위해 id
속성이 할당되어야 합니다.
Script
컴포넌트에 이벤트 핸들러를 사용하여 특정 이벤트가 발생한 후 추가 코드를 실행할 수 있습니다.
onLoad
: 스크립트 로딩이 완료된 후 코드 실행onReady
: 스크립트 로딩이 완료된 후, 컴포넌트가 마운트될 때마다 코드 실행onError
: 스크립트 로딩이 실패한 경우 코드 실행import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
onLoad={() => {
console.log('Script has loaded')
}}
/>
</>
)
}
각 이벤트 핸들러와 예제를 보려면 next/script
API 참조 문서를 참조하십시오.(https://nextjs.org/docs/api-reference/next/script#onload)
Script
컴포넌트에서 사용되지 않는 nonce
나 사용자 정의 데이터 속성과 같은 많은 DOM 속성이 할당될 수 있습니다.
추가된 모든 속성은 최종적으로 최적화된 HTML에 포함되는 <script>
요소로 전달됩니다.
import Script from 'next/script';
export default function Page() {
return (
<>
<Script
src='https://example.com/script.js'
id='example-script'
nonce='XUENAJFW'
data-test='script'
/>
</>
);
}