介紹/指南/腳本

如何載入與最佳化腳本

佈局腳本

若要為多個路由載入第三方腳本,請匯入 next/script 並直接在您的佈局元件中包含該腳本:

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 並直接在您的根佈局中包含該腳本:

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:(實驗性)在網頁工作者中載入腳本。

請參閱 next/script API 參考文件,以了解每種策略及其使用案例的更多資訊。

將腳本卸載至網頁工作者(實驗性)

警告worker 策略尚未穩定,且尚未與 App Router 一起使用。請謹慎使用。

使用 worker 策略的腳本會被卸載並在 Partytown 的網頁工作者中執行。這可以透過將主執行緒專用於應用程式的其餘程式碼來提升網站效能。

此策略仍處於實驗階段,只有在 next.config.js 中啟用 nextScriptWorkers 標誌時才能使用:

next.config.js
module.exports = {
  experimental: {
    nextScriptWorkers: true,
  },
}

然後,執行 next(通常是 npm run devyarn dev),Next.js 將引導您完成安裝所需套件的設定:

Terminal
npm run dev

您會看到類似以下的指示:請執行 npm install @builder.io/partytown 來安裝 Partytown

設定完成後,定義 strategy="worker" 將自動在您的應用程式中實例化 Partytown,並將腳本卸載至網頁工作者。

import Script from 'next/script'

export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="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')`,
  }}
/>

警告:必須為內聯腳本分配 id 屬性,以便 Next.js 追蹤和最佳化腳本。

執行額外程式碼

事件處理器可以與 Script 元件一起使用,以在特定事件發生後執行額外程式碼:

  • onLoad:在腳本完成載入後執行程式碼。
  • onReady:在腳本完成載入後以及每次元件掛載時執行程式碼。
  • onError:如果腳本載入失敗,執行程式碼。

這些處理器僅在 next/script 被匯入並在 客戶端元件 中使用時才會工作,其中 "use client" 被定義為程式碼的第一行:

'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 參考以了解每個事件處理器的更多資訊並查看範例。

其他屬性

有許多 DOM 屬性可以分配給 <script> 元素,這些屬性未被 Script 元件使用,例如 nonce自訂資料屬性。包含任何其他屬性將自動將其轉發到最終最佳化的 <script> 元素,該元素包含在 HTML 中。

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"
      />
    </>
  )
}

On this page