Skip to main content

脚本优化

布局脚本

¥Layout Scripts

要加载多个路由的第三方脚本,请导入 next/script 并将该脚本直接包含在布局组件中:

¥To load a third-party script for multiple routes, import next/script and include the script directly in your layout component:

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 将确保脚本仅加载一次,即使用户在同一布局中的多个路由之间导航也是如此。

¥The third-party script is fetched when the folder route (e.g. dashboard/page.js) or any nested route (e.g. dashboard/settings/page.js) is accessed by the user. Next.js will ensure the script will only load once, even if a user navigates between multiple routes in the same layout.

应用脚本

¥Application Scripts

要为所有路由加载第三方脚本,请导入 next/script 并将该脚本直接包含在根布局中:

¥To load a third-party script for all routes, import next/script and include the script directly in your root layout:

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 将确保脚本仅加载一次,即使用户在多个页面之间导航也是如此。

¥This script will load and execute when any route in your application is accessed. Next.js will ensure the script will only load once, even if a user navigates between multiple pages.

推荐:我们建议仅在特定页面或布局中包含第三方脚本,以尽量减少对性能的不必要影响。

¥Recommendation: We recommend only including third-party scripts in specific pages or layouts in order to minimize any unnecessary impact to performance.

战略

¥Strategy

尽管 next/script 的默认行为允许你在任何页面或布局中加载第三方脚本,但你可以使用 strategy 属性微调其加载行为:

¥Although the default behavior of next/script allows you to load third-party scripts in any page or layout, you can fine-tune its loading behavior by using the strategy property:

  • beforeInteractive:在任何 Next.js 代码之前以及任何页面水合发生之前加载脚本。

    ¥beforeInteractive: Load the script before any Next.js code and before any page hydration occurs.

  • afterInteractive:(默认)尽早加载脚本,但要在页面发生一些水合作用之后。

    ¥afterInteractive: (default) Load the script early but after some hydration on the page occurs.

  • lazyOnload:稍后在浏览器空闲时加载脚本。

    ¥lazyOnload: Load the script later during browser idle time.

  • worker:(实验性)将脚本加载到 Web Worker 中。

    ¥worker: (experimental) Load the script in a web worker.

请参阅 next/script API 参考文档,了解有关每种策略及其用例的更多信息。

¥Refer to the next/script API reference documentation to learn more about each strategy and their use cases.

将脚本卸载到 Web Worker(实验性)

¥Offloading Scripts To A Web Worker (experimental)

警告:worker 策略尚未稳定,尚不能与 app 目录配合使用。谨慎使用。

¥Warning: The worker strategy is not yet stable and does not yet work with the app directory. Use with caution.

使用 worker 策略的脚本将在具有 Partytown 的 Web Worker 中卸载并执行。这可以通过将主线程专用于应用代码的其余部分来提高站点的性能。

¥Scripts that use the worker strategy are offloaded and executed in a web worker with Partytown. This can improve the performance of your site by dedicating the main thread to the rest of your application code.

该策略仍处于实验阶段,只有在 next.config.js 中启用 nextScriptWorkers 标志时才能使用:

¥This strategy is still experimental and can only be used if the nextScriptWorkers flag is enabled in next.config.js:

module.exports = {
experimental: {
nextScriptWorkers: true,
},
}

然后,运行 next(通常是 npm run devyarn dev),Next.js 将引导你安装所需的软件包以完成设置:

¥Then, run next (normally npm run dev or yarn dev) and Next.js will guide you through the installation of the required packages to finish the setup:

npm run dev

你会看到类似这样的说明:请运行 npm install @builder.io/partytown 安装 Partytown

¥You'll see instructions like these: Please install Partytown by running npm install @builder.io/partytown

设置完成后,定义 strategy="worker" 将自动在你的应用中实例化 Partytown 并将脚本卸载给 Web Worker。

¥Once setup is complete, defining strategy="worker" will automatically instantiate Partytown in your application and offload the script to a web worker.

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 Worker 中加载第三方脚本时需要考虑许多权衡。请参阅 Partytown 的 tradeoffs 文档以获取更多信息。

¥There are a number of trade-offs that need to be considered when loading a third-party script in a web worker. Please see Partytown's tradeoffs documentation for more information.

内联脚本

¥Inline Scripts

脚本组件还支持内联脚本或不从外部文件加载的脚本。它们可以通过将 JavaScript 放在大括号内来编写:

¥Inline scripts, or scripts not loaded from an external file, are also supported by the Script component. They can be written by placing the JavaScript within curly braces:

<Script id="show-banner">
{`document.getElementById('banner').classList.remove('hidden')`}
</Script>

或者使用 dangerouslySetInnerHTML 属性:

¥Or by using the dangerouslySetInnerHTML property:

<Script
id="show-banner"
dangerouslySetInnerHTML={{
__html: `document.getElementById('banner').classList.remove('hidden')`,
}}
/>

警告:必须为内联脚本分配 id 属性,以便 Next.js 跟踪和优化脚本。

¥Warning: An id property must be assigned for inline scripts in order for Next.js to track and optimize the script.

执行附加代码

¥Executing Additional Code

事件处理程序可以与脚本组件一起使用,以便在某个事件发生后执行附加代码:

¥Event handlers can be used with the Script component to execute additional code after a certain event occurs:

  • onLoad:脚本加载完成后执行代码。

    ¥onLoad: Execute code after the script has finished loading.

  • onReady:在脚本完成加载后以及每次安装组件时执行代码。

    ¥onReady: Execute code after the script has finished loading and every time the component is mounted.

  • onError:如果脚本加载失败则执行代码。

    ¥onError: Execute code if the script fails to load.

这些处理程序仅在 next/script 被导入并在 客户端组件 内部使用时才起作用,其中 "use client" 被定义为第一行代码:

¥These handlers will only work when next/script is imported and used inside of a Client Component where "use client" is defined as the first line of code:

'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 参考以了解有关每个事件处理程序的更多信息并查看示例。

¥Refer to the next/script API reference to learn more about each event handler and view examples.

附加属性

¥Additional Attributes

有许多 DOM 属性可以分配给脚本组件未使用的 <script> 元素,例如 nonce自定义数据属性。包含任何其他属性都会自动将其转发到 HTML 中包含的最终优化的 <script> 元素。

¥There are many DOM attributes that can be assigned to a <script> element that are not used by the Script component, like nonce or custom data attributes. Including any additional attributes will automatically forward it to the final, optimized <script> element that is included in the 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"
/>
</>
)
}
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"
/>
</>
)
}