跳至內容

腳本優化

應用程式指令碼

要載入所有路由的第三方指令碼,請匯入 next/script 並將指令碼直接包含在您的自訂 _app 中。

pages/_app.js
import Script from 'next/script'
 
export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
      <Script src="https://example.com/script.js" />
    </>
  )
}

當存取應用程式中的任何路由時,此指令碼將會載入並執行。 Next.js 將確保指令碼只會載入一次,即使使用者在多個頁面之間導覽也是如此。

建議:我們建議只在特定頁面或佈局中包含第三方指令碼,以盡量減少對效能的不必要影響。

策略

雖然 next/script 的預設行為允許您在任何頁面或佈局中載入第三方指令碼,但您可以使用 strategy 屬性來微調其載入行為。

  • beforeInteractive:在任何 Next.js 程式碼和任何頁面水合作用發生之前載入指令碼。
  • afterInteractive:(預設值)在頁面上發生一些水合作用後及早載入指令碼。
  • lazyOnload:在瀏覽器閒置期間延遲載入指令碼。
  • worker:(實驗性)在 Web Worker 中載入指令碼。

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

將指令碼卸載到 Web Worker(實驗性)

警告:worker 策略尚未穩定,且尚無法與 app 目錄一起使用。請謹慎使用。

使用 worker 策略的指令碼會被卸載並在使用 Partytown 的 Web Worker 中執行。這可以透過將主執行緒專用於應用程式程式碼的其餘部分來提高網站的效能。

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

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

接著,執行 next(通常是 npm run devyarn dev),Next.js 會引導您安裝所需的套件以完成設定。

終端機
npm run dev

您將看到如下指示:請透過執行 npm install @builder.io/partytown 來安裝 Partytown。

設定完成後,定義 strategy="worker" 將會自動在您的應用程式中實例化 Partytown,並將程式碼卸載到 Web Worker。

pages/home.tsx
import Script from 'next/script'
 
export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  )
}

在 Web Worker 中載入第三方腳本時,需要考慮一些取捨。請參閱 Partytown 的取捨 文件以了解更多資訊。

使用自訂 Partytown 設定

雖然 worker 策略不需要任何額外設定即可運作,但 Partytown 支援使用設定物件來修改部分設定,包括啟用 debug 模式以及轉發事件和觸發器。

如果您想新增其他設定選項,可以將其包含在自訂 _document.js 中使用的 <Head /> 元件內。

_pages/document.jsx
import { Html, Head, Main, NextScript } from 'next/document'
 
export default function Document() {
  return (
    <Html>
      <Head>
        <script
          data-partytown-config
          dangerouslySetInnerHTML={{
            __html: `
              partytown = {
                lib: "/_next/static/~partytown/",
                debug: true
              };
            `,
          }}
        />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

要修改 Partytown 的設定,必須符合以下條件:

  1. 必須使用 data-partytown-config 屬性來覆寫 Next.js 使用的預設設定。
  2. 除非您決定將 Partytown 的程式庫檔案儲存在不同的目錄中,否則設定物件中必須包含 lib: "/_next/static/~partytown/" 屬性和值,以便讓 Partytown 知道 Next.js 儲存必要靜態檔案的位置。

注意:如果您正在使用資源前綴,並且想要修改 Partytown 的預設設定,則必須將其包含在 lib 路徑中。

請查看 Partytown 的設定選項以查看可以新增的其他屬性的完整清單。

內嵌程式碼

腳本元件也支援內嵌程式碼,或未從外部檔案載入的程式碼。它們可以透過將 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" 定義為程式碼的第一行。

pages/index.tsx
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自訂資料屬性。包含任何額外屬性將會自動將其轉送至最終包含在 HTML 中的已最佳化 <script> 元素。

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