STATUS IS UP网站优化 Wiki
25加速
性能与交付 / 加速

JavaScript 性能:减少主线程工作量

查找导致页面卡顿或延迟的 JavaScript,删除不必要的工作,并保护关键交互流程。

JavaScript 性能:减少主线程工作量 — 可视化指南
阅读
8 分钟
来源
5
重新验证
2027-03-27
已审阅
高级网页性能评审(Senior Web Performance Reviewer)
简短回答

从决策开始。

通过对真实页面和交互进行测量,减少主线程工作量,然后修复最显著且可重复的成本。主线程以任务为单位串行运行大部分页面 JavaScript 和界面工作。超过 50 毫秒的任务被视为长任务,因此一次点击、触摸、滚动或一次绘制可能必须等待其完成。优先从结账、搜索、导航、表单和其他敏感路径开始。

针对每项成本,删除它、延迟到需要时再执行、将其拆分为短批次,或将范围明确的计算移至 Web Worker。将用户可感知的即时响应保留在主线程,把分析和其他非必要的后续工作推迟执行。将每个第三方标签都视为有明确负责人的依赖项。在受限的移动端 CPU 上重新测试,并为关键流程保留回滚方案。

可视化指南

把工作看作一个系统。

使用此地图在执行具体策略前将文章中的决策联系起来。

SIU加速
01在改代码前先分析一次客户旅程
02把追踪当作工作队列来阅读
03在关键时刻交付更少代码
04把工作拆分,使浏览器能响应
01

在改代码前先分析一次客户旅程

选择一个重要的路由和交互,例如打开导航、筛选结果或提交表单。在 Chrome DevTools 的 Performance 面板中以干净的浏览器状态录制一次操作。重复该动作并捕获受限 CPU(throttled-CPU)运行和开发机器运行两种追踪;桌面追踪可能会隐藏在低功耗手机上会造成干扰的工作。

使用追踪来验证一个窄范围假设,而不是用 bundle 报告来责怪某个组件。在 Main 火焰图(Main flame chart)中,越宽的条表示耗时越长,堆叠条表示调用栈。任务上的红色三角标识潜在长任务;选中它并跟随发起代码链接。保存前后追踪以证明有意义的改进。

捕捉关键时刻

在动作之前开始录制,并在可见结果出现后停止。

使用可重复用的用例

保持路由、账号状态和动作顺序一致。

指定负责人

把每个主要成本分配给能够修改它的团队或供应商。

02

把追踪当作工作队列来阅读

长任务是一个调查阈值,而不是完整诊断。W3C 的 Long Tasks 规范将持续 50 毫秒或以上的任务报告为长任务。深入查看一个任务下的 JavaScript 求值、事件处理器、样式重算、布局或绘制。调用栈指明从哪里开始;时间信息显示问题是代码、渲染,还是第三方 iframe 导致的。

优先处理在有价值的交互中反复出现的成本。短的处理器仍可能因为触发布局或排在之前的工作后面而感觉缓慢。追踪是实验室测量,因此要在代表性设备上并在可用时结合注重隐私的现场遥测来确认修复效果。

区分不同时刻的工作

启动时的解析需要与点击后处理的不同修复策略。

检查渲染相关

在重构前找到重复的写样式/读布局模式。

保留基线

把追踪、场景和主要成本附到工作项里。

03

在关键时刻交付更少代码

按路由和用途清点脚本。移除未使用的包、重复项、已下线的实验和已结束功能的代码。然后把路由特定或很少使用的功能拆分开,让它们在需要时加载,而不是在初始路径中加载。动态加载可减少启动工作,但在用户立即需要功能时可能产生可见延迟。

问问自己一个组件是否真的需要完整的客户端框架、一个工具库是否重复了已有能力,以及静态 HTML 加少量增强是否足够。测试延迟模块的回退状态。页面应优雅地推迟可选能力,而不是显示一个失效的控制项。

制定路由预算

记录每个路由允许加载的脚本及其原因。

按意图加载

对可选编辑器、地图、播放器或报告视图考虑此做法。

保护关键路径

测试认证、无障碍、支付和表单完成;在控件受影响时寻求合格评审。

04

把工作拆分,使浏览器能响应

把小函数命名并不会在同步运行时创建多个浏览器任务。对于长循环,要把工作分批、先更新用户可见的立即状态,然后在继续之前让出(yield)。这允许浏览器在批次间处理输入和渲染。

在支持的环境下,scheduler.yield() 可以让出主线程并在稍后继续工作;要进行特性检测并为不支持的浏览器提供回退方案。不要在每个微小操作后都让出:这有开销,可能会增加完成时间。从测量中选择合适的边界,保留取消能力,并避免过时结果覆盖更新状态。

界面优先

在不可见的后续工作前先显示接受或进度反馈。

按已耗时间分批

在测得工作即将变长前让出,而不是每项后都让出。

避免过时捷径

当前 web.dev 指南不建议基于 isInputPending() 的新策略。

05

把计算移动到 worker,但别移动界面逻辑

Web Worker 在与主执行线程分离的后台线程上运行脚本。它适合耗费 CPU 的解析、数据转换、搜索索引和其他不需要直接访问界面的计算。传入定义的输入,返回定义的结果,并把渲染和可见状态变更保留在主线程上。

Workers 并非全能。它们不能直接操作 DOM 或使用 Window,且通用消息通信会复制数据。Worker 的创建、数据移动和错误协调可能会超过一次小型计算的开销。测量完整交互、终止不再需要的 worker,并在 worker 失败时设计回退方案。

选择可隔离的工作

从输入和输出可以序列化并可测试的计算开始。

给消息版本号

丢弃为较旧的过滤器、路由或动作产生的结果。

保留可访问性

通过正常界面传达有意义的进度信息。

06

把第三方 JavaScript 当作生产依赖来治理

分析、广告、实验、社交嵌入、视频播放器和客服小组件都会增加请求、JavaScript 求值、iframe 和依赖项。供应商脚本可能必不可少,但不在应用团队的直接控制范围内,并可能影响性能、隐私、安全与业务连续性。清点其用途、适用路由、加载条件、审批人、同意要求和负责移除的人员。

在条件与合同允许的情况下,对比代表性页面在有无某个第三方源时的表现。性能工具可以暴露昂贵的求值、负载和长任务归因。仅当文档化的价值能证明经过测量的成本时,保留轻量或延迟集成。可选依赖变慢或缺失时,确认核心内容和主要事务仍能正常工作。

限制波及范围

仅在需要的路由和条件下加载标签。

复核变更控制

把标签管理器的更改纳入性能、隐私、安全和回滚评审。

保留移除开关

记录并测试如何禁用非关键集成。

07

把响应性当作发布保护点

把成功的追踪做成对重要路径的小型回归校验。定义覆盖的交互、设备或 CPU 约束、预期响应和评审者。把它与 bundle 和第三方清单复核配对,防止新包或标签悄然重新引入主线程工作。

Status Is UP 使用这些证据进行主动优化和安全修复,而不是替代在线可用性监控。在高风险变更前,准备回滚并在发布后验证关键流程。结果会随设备、网络、浏览器、内容和账号状态不同;把阈值当作护栏(guardrails),而非保证。

对重大变更设门槛

对共享导航、结账、搜索或大型 bundle 要求提交前后追踪。

练习回滚

了解能恢复到已知良好行为的功能标志、标签设置或部署版本。

定期复盘

在重大发布、供应商变更或设备组合变化后重新分析。

行动 / 验证

你的实用待办指南。

  1. 01

    选择一个关键交互

    命名路由、动作、预期响应和对客户的影响。

    验证: 测试记录包含路由、账号状态、动作、浏览器和设备或 CPU 设置。
  2. 02

    记录基线

    在干净状态下用 DevTools Performance 录制该交互。

    验证: 团队可以用 Main 火焰图重新查看追踪。
  3. 03

    查找阻塞工作

    检查长任务、调用栈、渲染和第三方活动。

    验证: 每个主要成本都有持续时间、来源或域、路由和负责人。
  4. 04

    移除不必要的脚本

    删除未使用的包、已下线的实验、重复项和不需要的路由代码。

    验证: 构建和关键旅程在移除后仍能工作。
  5. 05

    延迟可选功能

    仅在需要时再加载可选能力,且其延迟状态仍可用。

    验证: 在新页面加载测试覆盖加载、失败或回退情形。
  6. 06

    拆分长任务

    把工作分批并在即时界面响应后让出。

    验证: 新的追踪移除了相应交互路径的长任务并保留正确结果。
  7. 07

    评估使用 worker 的可行性

    仅将消息格式明确、范围可控的计算移至 Web Worker。

    验证: 测试端到端的时序、错误、过时结果和清理。
  8. 08

    审计第三方

    记录目的、负责人、触发条件、同意、成本和禁用流程。

    验证: 每个关键路由的标签都有保留、限制、延迟或移除的决策记录。
  9. 09

    在受限条件下测试

    在受限 CPU(throttled CPU)和代表性浏览器或设备上重复测试(如可行)。

    验证: 比较使用相同场景并记录重要差异。
  10. 10

    发布并具备回滚能力

    把追踪、验收检查和回退指令附到发布中。

    验证: 指定负责人无需翻找未记录的信息,即可恢复已知正常的行为。
讨论主题

比较各种权衡,而不是私有数据。

与团队或网站所有者社区一起使用这些提示。共享方法与经验,但切勿粘贴凭证、客户记录或非公开的基础设施细节。

  1. 01

    哪个交互在加载报告中看起来可接受,但在你针对真实点击或触摸做性能分析时证明很慢?

  2. 02

    你如何决定一个第三方功能是否值得其测得的主线程成本?

  3. 03

    哪种回滚机制能最容易在不破坏关键流程的情况下逆转性能回归?

热门 / 权威资源

打开来源材料。

web.devOptimize long tasks ↗

解释长任务、让出(yield)、scheduler.yield()、回退以及让出的开销。

已审阅 2026-09-27
Chrome for DevelopersAnalyze runtime performance ↗

展示如何录制、分析火焰图、识别长任务并追溯来源。

已审阅 2026-09-27
MDN Web DocsWeb Workers API ↗

定义 Workers、消息通信及其不能直接访问 DOM 的限制。

已审阅 2026-09-27
web.devLoad Third-Party JavaScript ↗

提供第三方脚本审计与测量的指南。

已审阅 2026-09-27
W3CLong Tasks API ↗

定义长任务、阈值及其归因方法。

已审阅 2026-09-27

来源政策。 本文基于编辑团队阅读的官方浏览器、标准与 web 平台文档。文中区分了测量与保证,并省略了不支持的声明。

快速说明

常见问题。

什么算是长的 JavaScript 任务?

W3C 的 Long Tasks 规范将 50 毫秒或以上的任务作为报告阈值。这是一个需要调查的信号,而不是证明较短任务就无害。请在追踪中确认原因。

代码拆分(code splitting)总是能改善 JavaScript 性能吗?

不是。拆分可以减少启动工作,但会增加首次使用时的延迟。把它用于路由特定或可选代码,并在受限条件下测试该功能。

每个昂贵的函数都应该在 Web Worker 中运行吗?

不必。Web Worker 适合处理输入和输出明确、可独立运行且消耗大量 CPU 的计算。它们不能直接修改 DOM,数据传输有成本,而小任务在主线程上完成可能更快。

Status Is UP Editorial Team · 可用性赋能编辑(Uptime Enablement Editors)

由 高级网页性能评审(Senior Web Performance Reviewer) 审阅。发布于 2026-09-27;更新于 2026-09-30。