前端性能清单之 legacy-js:如何停止向现代浏览器投放 ES5 代码与 Polyfill
2026/9/19 5:29:34 网站建设 项目流程

前端性能清单之 legacy-js:如何停止向现代浏览器投放 ES5 代码与 Polyfill

【免费下载链接】Front-End-Checklist🗂 The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist

导读

本文基于 Front-End-Checklist 仓库中的legacy-js规则展开,系统讲解"避免向现代浏览器提供遗留 JavaScript(legacy JavaScript)"这一性能优化项。你将掌握差异化交付(differential serving)的 module/nomodule 实现方式、Vite 与 Browserslist 的现代化编译目标配置、Polyfill 的审计方法,以及如何用 Lighthouse、PageSpeed Insights 与 DevTools 网络瀑布流验证优化结果。读完本文,你可以在自己的构建链路上直接落地一套"给现代浏览器发现代代码"的优化方案。

规则概览:legacy-js 是什么

在 Front-End-Checklist 仓库中,这条规则以两种载体存在:一是面向 Agent 的技能文件 skills/legacy-js/SKILL.md,二是承载完整规则数据的内容文件 packages/content/rules/en/performance/legacy-js.mdx,同时被收录在 docs/generated/rules-catalog.md 的清单中。

规则的定义非常明确:

Detects ES5 polyfills and legacy JavaScript code to reduce bundle size and improve execution(检测 ES5 polyfill 与遗留 JavaScript 代码,以减小包体积并提升执行性能)

其核心论断是:现代浏览器原生支持 ES6+,且执行 ES6+ 代码比执行转译后的 ES5 更快、更高效;如果把这些浏览器当作老浏览器对待,向它们下发转译后的 ES5 代码和冗余 polyfill,就是白白增加了页面重量。

该规则在仓库中的元数据标注为:

属性
分类(category)performance
子分类(subcategory)metrics
优先级(priority)medium
难度(difficulty)intermediate
预估耗时(estimatedTime)10 分钟
数据来源(source)frontendchecklist.io

技能文件的 SKILL.md 还给出了它的适用场景:在审计页面加载缓慢、资源过重或渲染延迟时使用,并且在提出改动建议前,必须先通过 DevTools、Lighthouse 或现场数据(field data)确认真正的瓶颈所在——这条规则强调的是"用数据说话",而不是凭感觉优化。

Quick Reference:三条快速行动要点

规则首先给出三条速查要点,它们也是整条规则的纲领:

  1. 使用差异化交付(module/nomodule),分别面向现代浏览器与遗留浏览器投放代码;
  2. 避免为支持 ES6+ 的浏览器引入重型 ES5 polyfill
  3. 将代码编译到现代目标(modern target),从而减小包体积、提升执行速度。

这三点分别对应了"投送方式""依赖策略"和"编译配置"三个层面,下文会逐一展开。

为什么要避免向现代浏览器下发 ES5 代码

原生 ES6+ 的执行优势

绝大多数流量来自原生支持 ES6+ 的现代浏览器。规则原文明确指出:

Modern browsers can execute ES6+ code faster and more efficiently; serving them transpiled ES5 with polyfills adds unnecessary weight.

把类(class)、箭头函数(arrow function)等语法转译成 ES5 后,浏览器需要解析更多的指令、执行更多的兼容逻辑;而现代浏览器可以直接执行原生 ES6+ 语法,解析与执行路径都更短。仓库的完整规则文档 references/rule.md 中,将这种差异总结为四个维度的收益:

  • 包体积(Bundle Size):ES6+ 语法往往比转译后的 ES5 更简洁,文件更小;
  • 执行速度(Execution Speed):现代浏览器执行原生 ES6+ 特性(如 class、箭头函数)快于其转译等价物;
  • Polyfill 过载(Polyfill Overload):大量 polyfill 对绝大多数用户完全没有必要,只会拖慢体验;
  • 代码维护(Code Maintenance):编写和调试现代 JavaScript 远比维护重度转译后的产物容易。

转译与 Polyfill 的隐性成本

"把所有代码转译到 ES5 并给一切特性打 polyfill"是过时的做法。它带来三类隐性成本:

  1. 网络成本:转译产物更长、polyfill 额外增加请求体积,直接推高首屏传输字节数;
  2. 解析/编译成本:浏览器需要解析更复杂的 ES5 兼容代码,占用主线程 CPU 时间,拖慢可交互时间;
  3. 维护成本:多层转译引入的 source map 与调试链路问题,让线上问题定位更加困难。

Check:如何检查项目中是否存在多余的 ES5 代码

规则的check提示词是:

Analyze the project's JavaScript output to see if modern browsers are being served unnecessary ES5 code and polyfills.

具体检查路径可分为三步:

  1. 查看构建产物目标:检查打包器(Vite、webpack、Babel 等)配置中的target/preset-env/browserslist,确认是否把全部用户当成老浏览器处理;
  2. 审查 polyfill 引入方式:在产物中搜索core-jsregenerator-runtimewhatwg-fetch等 polyfill 的痕迹,确认是否通过useBuiltIns: 'usage'按需引入,还是全量注入;
  3. 在真实浏览器中观察:用 Lighthouse 或 DevTools 打开目标路由,查看是否有legacy-javascript审计项告警,以及在网络瀑布流中是否仍下载了 ES5 转换后的 chunk。

Front-End-Checklist 规则的前置条件强调:先验证瓶颈,再提建议。技能文件的 metadata 中专门注明"Verify the actual bottleneck in DevTools, Lighthouse, or field data before recommending changes",即不要仅凭本地构建输出做判断,而要结合真实用户环境的数据。

Fix:三种落地修复方案

规则的fix提示词是:

Update the build configuration to use differential serving and set a modern target for your primary JavaScript output.

下面给出规则文档中的三种具体实现,均为可直接复制的配置。

方案一:HTML 层面的差异化交付(Differential Serving)

差异化交付的核心思想是:让现代浏览器加载现代代码,让老浏览器加载遗留代码。规则文档给出的 HTML 模板:

<!-- ✅ Good: Serve modern JS to modern browsers, legacy JS to old ones --> <script type="module" src="modern.js"></script> <script nomodule src="legacy.js"></script>

其原理是:支持 ES Modules 的浏览器会执行type="module"脚本并忽略nomodule属性,而不支持 ES Modules 的老浏览器会跳过type="module"脚本、执行nomodule脚本。这样一份 HTML 就能同时服务两类用户,且现代用户永远只下载现代代码。需要注意的是,nomodule脚本在现代浏览器中应配合正确构建(如将其 polyfill 内联以避免重复执行),主流打包器如 webpack 的module/nomodule配置会自动处理这些边界。

方案二:为 Vite 设置现代编译目标

规则文档给出的 Vite 配置:

// ✅ Good: Targeting modern browsers specifically export default { build: { target: 'esnext' // Or 'es2020', 'es2022' } }

build.target决定 Vite 对产物进行语法降级的程度:设为esnext表示完全不做语法转换,产出最大程度保持原貌;es2020es2022等则按 ES 版本边界降级。选型原则是"就高不就低"——只在你的浏览器支持基线允许的前提下尽可能用高版本目标,从而减小转译开销。

方案三:通过 Browserslist 声明真实浏览器目标

规则文档给出的.browserslistrc示例:

# ✅ Good: Specifying modern browsers to avoid unnecessary polyfills defaults and supports es6-module last 2 versions not dead

这段配置表达了三层含义:

  • defaults and supports es6-module:只针对支持 ES6 模块的默认浏览器集合;
  • last 2 versions:只覆盖每个浏览器最近的两个大版本;
  • not dead:排除官方已停止维护的浏览器(如 IE)。

Browserslist 是 Babel、PostCSS、Autoprefixer 等工具共同的浏览器兼容数据源,声明一个"现代且现实"的目标集合后,工具链会自动据此决定语法转换与 polyfill 的取舍,从而避免给现代浏览器注入用不上的兼容代码。

仓库实践参照:现代构建链路中的性能取向

虽然 Front-End-Checklist 的主站(apps/web/next.config.js)本身由 Next.js 构建、不直接配置 Browserslist,但它的配置集中体现了"现代目标 + 生产环境瘦身"的思路,可作为同类优化方向的参照:

// apps/web/next.config.js(节选) transpilePackages: ['@thedaviddias/analytics', '@frontendchecklist/rules', ...], compiler: { // Remove console.log in production removeConsole: process.env.NODE_ENV === 'production' }, images: { formats: ['image/avif', 'image/webp'], deviceSizes: [640, 828, 1200, 1920], imageSizes: [32, 64, 128, 256] }

其中transpilePackages只对需要转译的 workspace 包做处理、compiler.removeConsole在生产环境剔除调试日志、图片启用 AVIF/WebP 现代格式,都体现了"只给现代环境发必要的代码与资源"这一原则在真实项目中的具体化。你可以对照自己的构建配置,检查是否有类似的"现代优先"设置,或是否存在相反的"全量 ES5 + 全量 polyfill"策略。

Best Practices:四条最佳实践

规则文档总结了四条可直接执行的最佳实践:

  1. ✅ 使用差异化交付:为 90%+ 的用户投放小而快的代码;
  2. ✅ 设定现实的浏览器目标:用 Browserslist 精确定义你需要支持的浏览器集合,而不是"支持所有浏览器";
  3. ✅ 审计你的 Polyfill:使用core-js并开启useBuiltIns: 'usage',只引入实际用到的 polyfill;
  4. ✅ 优先使用原生特性:如果只支持现代浏览器,直接使用原生fetchPromise等 API,无需任何 polyfill。

其中useBuiltIns: 'usage'是 core-js 的按需引入模式:Babel 会扫描源码,只把实际使用到且目标浏览器缺失的 API 的 polyfill 打进产物,避免全量注入导致的体积膨胀。

Tools & Validation:用哪些工具验证

规则文档强调:在修改构建目标之前,先用 PageSpeed Insights 或你的 bundle 报告确认收益——实战收益通常来自"确认现代浏览器仍在下载哪些遗留 polyfill 或转译 chunk"。

  • Browserslist:用于核实实际的现代浏览器目标;
  • Polyfill.io:当你仍需要选择性支持老浏览器时应谨慎使用;
  • Lighthouse:可以在路由上标记legacy-javascript审计项;
  • Bundle 分析器(如vite-bundle-visualizerwebpack-bundle-analyzer):用于确认哪些 polyfill 或转换仍占据产物主导地位。

Standards:衡量标准

规则文档给出的测量标准是"以最终生产行为为准,而非本地合成输出":

  • web.dev: Learn Performance作为衡量最终生产行为的标准;
  • Chrome Developers: Lighthouse overview作为衡量最终生产行为的标准。

这意味着优化是否有效,要以生产环境真实页面的指标为准,而不是看本地构建的输出规模。

Verification:如何验证改动生效

自动化检查

  • 在 Lighthouse、PageSpeed Insights 或 DevTools 中测量受影响页面或流程,确认目标指标确实改善;
  • 检查网络瀑布流或性能时间线,确认预期的资源或执行变化确实发生。

手动检查

  • 节流的移动端配置下验证改动,而不只是在本地桌面环境;
  • 如果该规则对应某个预算(budget)或 Web Vitals 指标,确认页面保持在阈值之内。

这两条验证路径与技能的Code Review要求一脉相承:审查路由、资源和加载行为对legacy-js的影响,精确标记增加不必要网络、CPU 或布局成本的具体文件、请求或渲染步骤,并说明用于确认问题的测量方法

在 Front-End-Checklist 仓库中的延伸阅读

这条规则并非孤立存在。在 legacy-js.mdx 的 frontmatter 中,它与若干相关规则构成performance/metrics领域的关联网络,通常会被一起评审:

  • duplicate-js.mdx:避免重复加载 JavaScript,与 legacy-js 同属性能指标领域;
  • gtm-present.mdx:评估第三方脚本(如 GTM)的加载影响;
  • 以及javascript-minification(JS 压缩)、css-minification(CSS 压缩)等相邻规则。

如果想深入这条规则在 Agent 侧的执行方式,可以继续阅读 skills/legacy-js/SKILL.md 与其详细实现 references/rule.md;如果想了解规则在清单中的完整上下文,可查看 docs/generated/rules-catalog.md。整套仓库提供了从"规则定义 → 技能执行 → 站点应用"的完整链路,供你在自己的项目中对照落地。

【免费下载链接】Front-End-Checklist🗂 The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询