You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何useEffect会在浏览器绘制前触发?与useLayoutEffect的表现差异

为什么单独使用useEffect时会在浏览器绘制前触发?

你观察到的现象完全符合React的内部行为逻辑,核心原因是React的性能优化策略:

当组件中未使用useLayoutEffect时,React会尝试将useEffect的同步回调提前到浏览器绘制前执行——这样可以避免先渲染初始DOM、再执行useEffect可能引发的额外重绘或视觉闪烁,从而提升整体性能。

但只要组件中存在useLayoutEffect,React就会严格遵循标准的执行顺序:

  1. 执行所有useLayoutEffect回调(绘制前,阻塞绘制进程)
  2. 浏览器完成DOM绘制
  3. 执行所有useEffect回调(绘制后)

结合你的测试场景具体分析:

场景1:单独使用useEffect

performance.mark('start')
const App = () => {
  useEffect(() => {
    performance.mark('end-useEffect')
    performance.measure('useEffect triggered', 'start', 'end-useEffect');
  }, [])
  return (
    <div>123</div>
  )
}

单独使用useEffect的性能测量结果
由于没有useLayoutEffect存在,React触发了优化逻辑,把useEffect的执行时机提前到绘制前,所以性能测量结果显示它在绘制阶段之前完成。

场景2:同时使用useEffect与useLayoutEffect

performance.mark('start')
const App = () => {
  useEffect(() => {
    performance.mark('end-useEffect')
    performance.measure('useEffect triggered', 'start', 'end-useEffect');
  }, [])
  useLayoutEffect(() => {
    performance.mark('end-useLayoutEffect')
    performance.measure('useLayoutEffect triggered', 'start', 'end-useLayoutEffect');
  }, [])
  return (
    <div>123</div>
  )
}

同时使用两个hooks的性能测量结果
此时React需要优先保证useLayoutEffect的绘制前执行逻辑,因此会先完成所有useLayoutEffect回调,等待浏览器绘制完成后,再执行useEffect,这也符合我们对两者触发时机的常规认知。

内容的提问来源于stack exchange,提问作者Mia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 06:23:14