脚本优化
应用程序脚本
要为所有路由加载第三方脚本,请导入 next/script 并将脚本直接包含在你的自定义 _app 中
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 代码之前以及任何页面 hydration 发生之前加载脚本。afterInteractive:(默认)提前加载脚本,但在页面上发生一些 hydration 之后加载。lazyOnload:稍后在浏览器空闲时间加载脚本。worker:(实验性)在 Web Worker 中加载脚本。
请参阅 next/script API 参考文档,以了解有关每种策略及其用例的更多信息。
将脚本卸载到 Web Worker (实验性)
警告:
worker策略尚不稳定,尚不适用于 App Router。请谨慎使用。
使用 worker 策略的脚本会被卸载并在带有 Partytown 的 Web Worker 中执行。这可以通过将主线程专用于应用程序代码的其余部分来提高站点的性能。
此策略仍处于实验阶段,只有在 next.config.js 中启用 nextScriptWorkers 标志后才能使用
module.exports = {
experimental: {
nextScriptWorkers: true,
},
}然后,运行 next(通常是 npm run dev 或 yarn dev),Next.js 将指导你完成所需软件包的安装以完成设置
npm run dev你将看到如下说明:请运行 npm install @builder.io/partytown 安装 Partytown
设置完成后,定义 strategy="worker" 将自动在你的应用程序中实例化 Partytown,并将脚本卸载到 Web Worker。
import Script from 'next/script'
export default function Home() {
return (
<>
<Script src="https://example.com/script.js" strategy="worker" />
</>
)
}在 Web Worker 中加载第三方脚本时,需要考虑许多权衡。有关更多信息,请参阅 Partytown 的 tradeoffs 文档。
使用自定义 Partytown 配置
尽管 worker 策略不需要任何额外的配置即可工作,但 Partytown 支持使用 config 对象来修改其某些设置,包括启用 debug 模式以及转发事件和触发器。
如果你想添加其他配置选项,你可以将其包含在使用在 自定义 _document.js 中的 <Head /> 组件中
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 的配置,必须满足以下条件
- 必须使用
data-partytown-config属性才能覆盖 Next.js 使用的默认配置 - 除非你决定将 Partytown 的库文件保存在单独的目录中,否则必须在配置对象中包含
lib: "/_next/static/~partytown/"属性和值,以便让 Partytown 知道 Next.js 在哪里存储必要的静态文件。
注意:如果你正在使用 asset prefix 并且想要修改 Partytown 的默认配置,则必须将其作为
lib路径的一部分包含在内。
请查看 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" 被定义为代码的第一行
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"
/>
</>
)
}这有帮助吗?