Files
skillhub-088-vercel-react-b…/rules/rendering-script-defer-async.md
2026-07-13 21:36:17 +08:00

1.9 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
在 Script 标签上使用 defer 或 async HIGH 消除渲染阻塞 rendering, script, defer, async, performance

在 Script 标签上使用 defer 或 async

影响程度:高(消除渲染阻塞)

未使用 deferasync 的 Script 标签会在脚本下载和执行期间阻塞 HTML 解析。这会延迟首次内容绘制(First Contentful Paint)和可交互时间(Time to Interactive)。

  • defer:并行下载,HTML 解析完成后执行,保持执行顺序
  • async:并行下载,下载完成后立即执行,不保证执行顺序

对于依赖 DOM 或其他脚本的脚本,使用 defer。对于独立脚本(如分析工具),使用 async

错误做法(阻塞渲染):

export default function Document() {
  return (
    <html>
      <head>
        <script src="https://example.com/analytics.js" />
        <script src="/scripts/utils.js" />
      </head>
      <body>{/* content */}</body>
    </html>
  )
}

正确做法(非阻塞):

export default function Document() {
  return (
    <html>
      <head>
        {/* Independent script - use async */}
        <script src="https://example.com/analytics.js" async />
        {/* DOM-dependent script - use defer */}
        <script src="/scripts/utils.js" defer />
      </head>
      <body>{/* content */}</body>
    </html>
  )
}

注意: 在 Next.js 中,建议使用 next/script 组件配合 strategy 属性,而不是原生 script 标签:

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script src="https://example.com/analytics.js" strategy="afterInteractive" />
      <Script src="/scripts/utils.js" strategy="beforeInteractive" />
    </>
  )
}

参考文档:MDN - Script 元素