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

スクリプトの最適化

レイアウトスクリプト

複数のルートに対してサードパーティスクリプトをロードするには、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をインポートし、スクリプトを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はスクリプトを1回のみロードすることを保証します。同じページ上でユーザーが複数のページを移動しても、スクリプトは再ロードされません。

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

戦略

next/scriptのデフォルトの動作では、任意のページまたはレイアウトでサードパーティスクリプトをロードできますが、strategyプロパティを使用して、そのロード動作を微調整できます:

  • beforeInteractive: Next.jsのコードおよびページのハイドレーションが発生する前にスクリプトをロードします。
  • afterInteractive: (デフォルト) ページの一部がハイドレーションされた後にスクリプトを早期にロードします。
  • lazyOnload: ブラウザのアイドル時間中に後からスクリプトをロードします。
  • worker: (実験的) Webワーカー内でスクリプトをロードします。

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

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

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

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

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

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のトレードオフのドキュメントを参照してください。

インラインスクリプト

インラインスクリプト、つまり外部ファイルからロードされないスクリプトも、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')`,
}}
/>

警告:インラインスクリプトにはidプロパティを割り当て、Next.jsがスクリプトを追跡して最適化できるようにする必要があります。

追加のコードを実行する

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

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

これらのハンドラは、Client Component内に"use client"を最初の行として定義した状態で、next/scriptをインポートして使用する場合にのみ機能します:

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やカスタムデータ属性など。そのため、スクipt要素に追加の属性を含めると、自動的に最終的かつ最適化された<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"
/>
</>
)
}