コンテンツにスキップ

スクリプトの最適化

レイアウトスクリプト

複数のルートに対してサードパーティスクリプトを読み込むには、`next/script` をインポートし、レイアウトコンポーネントにスクリプトを直接記述します。

app/dashboard/layout.tsx
import Script from 'next/script'
 
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <>
      <section>{children}</section>
      <Script src="https://example.com/script.js" />
    </>
  )
}

サードパーティスクリプトは、フォルダールート (例: `dashboard/page.js`) またはネストされたルート (例: `dashboard/settings/page.js`) にユーザーがアクセスしたときにフェッチされます。Next.js は、ユーザーが同じレイアウト内の複数のルート間を移動した場合でも、スクリプトが**一度だけ読み込まれる**ことを保証します。

アプリケーションスクリプト
app/layout.tsx
import Script from 'next/script'
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
      <Script src="https://example.com/script.js" />
    </html>
  )
}

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

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

戦略 `next/script` APIリファレンスドキュメントを参照してください。

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

**警告:** `worker` 戦略はまだ安定しておらず、`app` ディレクトリではまだ機能しません。注意して使用してください。

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

この戦略はまだ実験段階であり、next.config.jsnextScriptWorkers フラグが有効になっている場合にのみ使用できます。

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

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

ターミナル
npm run dev

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

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

pages/home.tsx
import Script from 'next/script'
 
export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="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" が定義されているクライアントコンポーネント内で使用されている場合にのみ機能します。

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

追加属性

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

app/page.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"
      />
    </>
  )
}

APIリファレンス

next/script API の詳細はこちらをご覧ください。