スクリプト最適化

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

すべてのルートでサードパーティスクリプトを読み込むには、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ディレクトリでは動作しません。注意して使用してください。

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" />
    </>
  )
}
import Script from 'next/script'

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

Web Workerでサードパーティスクリプトを読み込む際には、考慮すべきトレードオフが多数あります。詳細については、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')
        }}
      />
    </>
  )
}
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リファレンスを参照してください。

追加属性

Scriptコンポーネントで使用されないnonceカスタムデータ属性など、<script>要素に割り当て可能な多くの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"
      />
    </>
  )
}
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"
      />
    </>
  )
}