Menu

スクリプトの読み込みと最適化方法

レイアウトスクリプト

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

app/dashboard/layout.tsx
TypeScript
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をインポートし、スクリプトを直接ルートレイアウトに含めます:

app/layout.tsx
TypeScript
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
TypeScript
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がインポートされ、"use client"がコードの最初の行として定義されているクライアントコンポーネント内で使用された場合にのみ機能します:

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

追加の属性

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

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