async/await 不改变浏览器性能指标本身,但通过优化异步逻辑组织显著影响FCP、LCP、TTI、CLS:避免主线程阻塞、支持并行请求、结合空闲调度、强化错误处理可提升各项指标。

async/await 本身不直接改变浏览器性能指标(如 FCP、LCP、TTI、CLS),但它显著影响这些指标的实现方式和优化空间——关键在于你如何用它组织异步逻辑,而非语法本身。
避免阻塞主线程,保障响应性
async/await 函数内部的 await 不会阻塞浏览器渲染线程,它只是暂停当前 async 函数的执行,把控制权交还给事件循环。这意味着:
- 后续同步代码(比如 DOM 操作、样式计算)仍可及时执行,不影响首屏绘制时间(FCP)
- 如果 await 后续操作耗时过长(如未优化的大图加载、未分片的数据解析),虽不阻塞线程,但可能延迟交互就绪时间(TTI)
- 错误地在关键路径上 await 长任务(如同步解析几 MB JSON),会推迟页面可交互状态
并行请求对 LCP 和 TTI 的实际影响
LCP(最大内容绘制)常取决于首屏关键资源(如 banner 图、主标题数据)的加载完成时间。用 async/await 写顺序请求,会拉长整体等待链:
- ❌ 顺序写法:await fetchBanner(); await fetchHeroText(); await fetchNav() → 总耗时 = 300ms + 200ms + 150ms = 650ms
- ✅ 并行写法:const [banner, text, nav] = await Promise.all([fetchBanner(), fetchHeroText(), fetchNav()]) → 总耗时 ≈ max(300ms, 200ms, 150ms) = 300ms
这直接缩短了 LCP 触发时机,也加快了数据就绪后 UI 渲染与用户可点击之间的间隔,对 TTI 有可观改善。
资源加载与空闲时段利用
借助 await 配合 requestIdleCallback 或 navigator.hardwareConcurrency,可在浏览器空闲期分批处理非关键异步任务:
- 例如:用 await 在空闲时段逐步解析大型配置文件,避免抢占主线程导致输入延迟(INP)升高
- 或在组件挂载后,用 await 延迟非首屏数据获取(如“猜你喜欢”),让 LCP 和 CLS 更稳定
- 注意:await 本身不触发空闲调度,需主动结合 IdleDeadline 使用
错误处理不当拖慢感知性能
未包裹 try/catch 的 await 抛错会导致 Promise rejection 未捕获,可能中断后续渲染逻辑或埋点上报:
- 一个未 catch 的 await fetch() 失败,可能让整个初始化流程卡住,延迟 hydration 完成,间接推高 TTI
- 建议对所有关键 await 加兜底:await Promise.race([fetch(...), timeout(8000)]),防止无限等待
- 使用 Promise.allSettled 替代 Promise.all,确保部分失败不影响其他资源加载节奏



















