スクリプトの最適化
レイアウトスクリプト
複数のルートに対してサードパーティスクリプトをロードするには、next/script
をインポートし、スクリプトを直接レイアウトコンポーネントに含めます:
- TypeScript
- JavaScript
import Script from 'next/script'
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<section>{children}</section>
<Script src="https://example.com/script.js" />
</>
)
}
import Script from 'next/script'
export default function DashboardLayout({ children }) {
return (
<>
<section>{children}</section>
<Script src="https://example.com/script.js" />
</>
)
}
サードパーティスクリプトは、フォルダルート(例:dashboard/page.js
)またはネストされたルート(例:dashboard/settings/page.js
)がユーザーによってアクセスされたときにフェッチされます。Next.jsはスクリプトを1回のみロードすることを保証します。同じレイアウト内でユーザーが複数のルートを移動しても、スクリプトは再ロードされません。
アプリケーションスクリプト
すべてのルートでサードパーティスクリプトをロードするには、next/script
をインポートし、スクリプトをroot レイアウトに直接含めます:
- TypeScript
- JavaScript
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>
)
}
import Script from 'next/script'
export default function RootLayout({ children }) {
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.js
でnextScriptWorkers
フラグが有効になっている場合のみ使用できます:
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ワーカーにオフロードされます。
- TypeScript
- JavaScript
import Script from 'next/script'
export default function Home() {
return (
<>
<Script src="https://example.com/script.js" strategy="worker" />
</>
)
}
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
をインポートして使用する場合にのみ機能します:
- TypeScript
- JavaScript
'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')
}}
/>
</>
)
}
'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にインクルードされます。
- TypeScript
- JavaScript
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"
/>
</>
)
}
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"
/>
</>
)
}