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はユーザーが同じレイアウト内の複数のルート間をナビゲートしても、スクリプトが1回だけ読み込まれることを保証します

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

すべてのルートに対してサードパーティスクリプトを読み込むには、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はユーザーが複数のページ間をナビゲートしても、スクリプトが1回だけ読み込まれることを保証します

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

Strategy(戦略)

next/scriptのデフォルトの動作ではサードパーティスクリプトを任意のページやレイアウトに読み込めますが、strategyプロパティを使用して読み込み動作を細かく調整できます。

  • beforeInteractive:Next.jsコードの前に、かつページハイドレーション前にスクリプトを読み込みます。
  • afterInteractive:(デフォルト)ページ上である程度ハイドレーションが発生した後、早期にスクリプトを読み込みます。
  • lazyOnload:ブラウザのアイドルタイム中に後からスクリプトを読み込みます。
  • worker:(実験的)Webワーカーでスクリプトを読み込みます。

各strategyとそのユースケースについて詳しく知るには、next/script APIリファレンスドキュメントを参照してください。

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

警告worker strategyはまだ安定していないため、App Routerではまだ機能しません。注意して使用してください。

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

このstrategyはまだ実験的であり、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プロパティを割り当てる必要があります。

追加コードの実行

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

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

追加属性

Scriptコンポーネントで使用されていない多くのDOM属性があり、nonceカスタムデータ属性などが挙げられます。追加の属性を含めると、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"
      />
    </>
  )
}