メインコンテンツまでスキップ

Script Optimization

レイアウトスクリプト

複数のルートに対してサードパーティのスクリプトを読み込むには、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 は、ユーザーが同じレイアウト内で複数のルートを移動しても、スクリプトが一度だけ読み込まれることを保証します。

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

すべてのルートに対してサードパーティのスクリプトを読み込むには、next/script をインポートし、スクリプトを直接 root レイアウトに含めます:

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 のデフォルトの動作では、任意のページやレイアウトでサードパーティのスクリプトを読み込むことができますが、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
import Script from 'next/script'

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

Web ワーカーでサードパーティのスクリプトを読み込む際には、考慮すべきトレードオフがいくつかあります。詳細については、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 がインポートされ、Client Component 内で使用される場合にのみ機能します。この場合、コードの最初の行として "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> 要素に割り当てることができる多くの DOM 属性があり、Script コンポーネントでは使用されません。例えば、nonceカスタムデータ属性 などです。追加の属性を含めると、自動的に最終的な最適化された <script> 要素に転送され、HTML に含まれます。

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