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'
/>
</>
);
}