NextJS: Optimizing Scripts

hwisaac·2023년 3월 12일
1

Next.js

목록 보기
15/29

Next.js의 Script 컴포넌트 (next/script)는 웹 애플리케이션의 어디에서나 최적의 성능으로 서드파티 스크립트를 로드할 수 있도록 해줍니다. HTML의 <script> 요소의 확장 기능이며, 사용 사례에 맞는 다양한 로딩 전략 중에서 선택할 수 있도록 제공합니다.

개요

웹 사이트는 분석, 광고, 고객 지원 위젯 및 동의 관리와 같은 기능을 추가하기 위해 종종 서드파티 스크립트를 사용합니다. 그러나 이렇게 하면 사용자 경험과 개발자 경험 모두에 영향을 미치는 문제가 발생할 수 있습니다.

  • 일부 서드파티 스크립트는 로딩 성능을 떨어뜨려 페이지 내용이 표시되는 것을 방해하므로 사용자 경험에 악영향을 미칠 수 있습니다.
  • 개발자는 종종 페이지 성능에 영향을 미치지 않고 애플리케이션에서 서드파티 스크립트를 어디서 어떻게 로드해야 할지 모릅니다.

브라우저는 HTML의 위치 및 asyncdefer 속성의 사용에 따라 <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 API 참조 문서를 참조하십시오.

참고: 브라우저에서 next/script 컴포넌트가 로드된 이후에는 이 컴포넌트가 DOM에 남아 있으므로 클라이언트 측 네비게이션으로 스크립트를 다시 실행하지 않습니다.

Offloading Scripts To A Web Worker (실험적 기능)

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

0개의 댓글