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

Script 最適化

レイアウト・スクリプト

複数のルートにサードパーティのスクリプトを読み込むには、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 は、ユーザーが同じレイアウト内の複数のルート間を移動しても、スクリプトが1 回しかロードされないようにします。

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

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

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 は、ユーザーが複数のページ間を移動しても、スクリプトが1 回しかロードされないようにします。

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

ストラテジー

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 devyarn dev)、セットアップを完了するために Next.js が必要なパッケージのインストールを案内します:

Terminal
npm run dev

次のような指示が表示されます:Please install Partytown by running npm install @builder.io/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 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"がコードの最初の行に定義されている Client Component で使用される場合にのみ機能します:

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

追加属性

<script>要素に割り当てることのできる DOM 属性には、nonceカスタム・データ属性のように、Script コンポーネントでは使用されないものがたくさんあります。追加属性を含めると、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 についてもっと知りたい場合は以下を参照してください。

/docs/app-router/api-reference/components/script