スクリプトの読み込みと最適化方法

アプリケーションスクリプト

すべてのルートでサードパーティスクリプトを読み込むには、next/scriptをインポートし、スクリプトを直接カスタム_appに含めます:

pages/_app.js
import Script from 'next/script'

export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
      <Script src="https://example.com/script.js" />
    </>
  )
}

このスクリプトは、アプリケーション内の任意のルートにアクセスしたときに読み込まれ実行されます。Next.jsは、ユーザーが複数のページ間を移動しても、スクリプトが一度だけ読み込まれることを保証します。

推奨事項: パフォーマンスへの不要な影響を最小限に抑えるため、サードパーティスクリプトは特定のページやレイアウトにのみ含めることを推奨します。

ストラテジー

next/scriptのデフォルトの動作では任意のページやレイアウトでサードパーティスクリプトを読み込めますが、strategyプロパティを使用して読み込み動作を微調整できます:

  • beforeInteractive: Next.jsのコードやページのハイドレーションが行われる前にスクリプトを読み込みます。
  • afterInteractive: (デフォルト)ページのハイドレーションが一部行われた後にスクリプトを早期に読み込みます。
  • lazyOnload: ブラウザのアイドル時間中に後でスクリプトを読み込みます。
  • worker: (実験的)スクリプトをWeb Workerで読み込みます。

各ストラテジーとそのユースケースについて詳しくは、next/script APIリファレンスドキュメントを参照してください。

Web Workerへのスクリプトオフロード(実験的)

警告: workerストラテジーはまだ安定しておらず、App Routerでは動作しません。注意して使用してください。

workerストラテジーを使用するスクリプトはPartytownを使用してWeb Workerにオフロードされ、実行されます。これにより、メインスレッドをアプリケーションコードの残りの部分に専念させることができ、サイトのパフォーマンスが向上します。

このストラテジーはまだ実験的であり、next.config.jsnextScriptWorkersフラグが有効になっている場合にのみ使用できます:

next.config.js
module.exports = {
  experimental: {
    nextScriptWorkers: true,
  },
}

その後、next(通常はnpm run devまたはyarn dev)を実行すると、Next.jsがセットアップを完了するために必要なパッケージのインストールを案内します:

Terminal
npm run dev

次のような指示が表示されます:npm install @builder.io/partytownを実行してPartytownをインストールしてください

セットアップが完了すると、strategy="worker"を定義すると、アプリケーションでPartytownが自動的に初期化され、スクリプトがWeb Workerにオフロードされます。

import Script from 'next/script'

export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  )
}

Web Workerでサードパーティスクリプトを読み込む際には、考慮すべきトレードオフがいくつかあります。詳細については、Partytownのトレードオフドキュメントを参照してください。

カスタムPartytown設定の使用

workerストラテジーは追加の設定なしで動作しますが、Partytownは設定オブジェクトを使用してdebugモードの有効化やイベント・トリガーの転送など、いくつかの設定を変更することをサポートしています。

追加の設定オプションを含めたい場合は、カスタム_document.jsで使用される<Head />コンポーネント内に含めることができます:

_pages/document.jsx
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html>
      <Head>
        <script
          data-partytown-config
          dangerouslySetInnerHTML={{
            __html: `
              partytown = {
                lib: "/_next/static/~partytown/",
                debug: true
              };
            `,
          }}
        />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

Partytownの設定を変更するには、以下の条件を満たす必要があります:

  1. Next.jsが使用するデフォルト設定を上書きするには、data-partytown-config属性を使用する必要があります
  2. Partytownのライブラリファイルを別のディレクトリに保存する場合を除き、設定オブジェクトにlib: "/_next/static/~partytown/"プロパティと値を含めて、PartytownにNext.jsが必要な静的ファイルを保存する場所を知らせる必要があります

: アセットプレフィックスを使用していてPartytownのデフォルト設定を変更する場合、libパスに含める必要があります。

他の追加可能なプロパティの完全なリストについては、Partytownの設定オプションを参照してください。

インラインスクリプト

外部ファイルから読み込まれないインラインスクリプトもScriptコンポーネントでサポートされています。中括弧内にJavaScriptを記述することで記述できます:

<Script id="show-banner">
  {`document.getElementById('banner').classList.remove('hidden')`}
</Script>

または、dangerouslySetInnerHTMLプロパティを使用することもできます:

<Script
  id="show-banner"
  dangerouslySetInnerHTML={{
    __html: `document.getElementById('banner').classList.remove('hidden')`,
  }}
/>

警告: インラインスクリプトには、Next.jsがスクリプトを追跡して最適化するためにidプロパティを割り当てる必要があります。

追加コードの実行

Scriptコンポーネントでイベントハンドラを使用すると、特定のイベント発生後に追加のコードを実行できます:

  • onLoad: スクリプトの読み込みが完了した後にコードを実行します。
  • onReady: スクリプトの読み込みが完了し、コンポーネントがマウントされるたびにコードを実行します。
  • onError: スクリプトの読み込みに失敗した場合にコードを実行します。

これらのハンドラは、next/scriptがインポートされ、"use client"がコードの最初の行として定義されたクライアントコンポーネント内で使用された場合にのみ機能します:

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リファレンスを参照してください。

追加属性

nonceカスタムデータ属性など、Scriptコンポーネントで使用されない多くのDOM属性を<script>要素に割り当てることができます。追加の属性を含めると、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"
      />
    </>
  )
}

On this page