Menu

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

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

すべてのルートに対してサードパーティスクリプトを読み込むには、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ワーカーでスクリプトを読み込みます。

各戦略とその使用例についての詳細は、next/scriptのAPIリファレンスドキュメントを参照してください。

スクリプトをWebワーカーにオフロードする(実験的)

注意: worker戦略はまだ安定しておらず、App Routerでは動作しません。慎重に使用してください。

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

この戦略はまだ実験的なもので、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ワーカーにオフロードされます。

pages/home.tsx
TypeScript
import Script from 'next/script'
 
export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  )
}

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

カスタムPartytownの設定を使用する

worker戦略は追加の設定なしで動作しますが、Partytownはdebugモードの有効化やイベントとトリガーの転送など、設定を変更するためのconfigオブジェクトの使用をサポートしています。

追加の設定オプションを含めたい場合は、カスタム_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プロパティを割り当てる必要があります。

追加コードの実行

イベントハンドラを使用して、特定のイベントが発生した後に追加コードを実行できます:

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

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

pages/index.tsx
TypeScript
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コンポーネントでは使用されない<script>要素に割り当てることができる多くのDOM属性があります。追加の属性を含めると、HTMLに含まれる最終的に最適化された<script>要素に自動的に転送されます。

pages/index.tsx
TypeScript
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"
      />
    </>
  )
}