コンテンツへスキップ

スクリプトの最適化

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

すべてのルートでサードパーティスクリプトを読み込むには、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.js`で`nextScriptWorkers`フラグが有効になっている場合にのみ使用できます。

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

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

ターミナル
npm run dev

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

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

pages/home.tsx
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のライブラリファイルを別のディレクトリに保存しない限り、Next.jsが必要な静的ファイルをどこに保存しているかをPartytownに知らせるために、`lib: "/_next/static/~partytown/"`プロパティと値が設定オブジェクトに含まれている必要があります。

: アセットプリフィックスを使用しており、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"`がコードの最初の行として定義されている場合にのみ機能します。

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

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