useEffect 与 useLayoutEffect 有什么区别?

先理解原理和示例,再练习完整口述与追问。

useLayoutEffect 在相关 DOM 提交后、浏览器绘制前执行,可用于需要避免闪烁的布局测量,但会阻塞绘制。useEffect 的绘制先后还受触发场景影响,不能保证永远在屏幕绘制后执行。

useLayoutEffect 在提交 DOM 后、浏览器有机会绘制之前执行,适合必须先测量再调整以避免可见跳动的少量布局工作;它会阻塞绘制。useEffect 用于一般外部同步,通常允许浏览器先绘制,但交互和调度细节不能承诺成永远在 paint 后。两者都不是服务端渲染时执行布局的方案。

浮层必须根据触发按钮位置决定上方或下方时,可以在 LayoutEffect 读取尺寸并设置位置,避免先显示错误位置再跳。事件订阅、日志和普通请求通常不必阻塞绘制。大量循环测量应先减少读写次数,不能仅因换成 LayoutEffect 就期待更快。

不要把所有 Effect 换成 LayoutEffect 来处理时序。SSR 首屏需有合理占位或服务端可确定的位置,不能访问不存在的 document 来测量。

useLayoutEffect 在 DOM 提交之后、绘制之前执行,适合测量后必须立即修正位置以免闪烁的场景,但同步工作会阻塞绘制。useEffect 通常更适合一般外部同步,它与绘制的先后还受交互调度影响,不能承诺总在 paint 后。没有布局测量需求时不应默认使用 layout Effect。

面试官可能继续问追问与完整解答展开收起

测量 tooltip 用哪个?为什么服务端不能执行真实布局测量?

tooltip 需要读尺寸再定位,且不想先闪一次错误位置时可用 useLayoutEffect。服务端没有真实浏览器布局,无法测量元素;服务端输出稳定占位或初始结构,客户端挂载后再做必要测量。