WHAT - React startTransition vs setTimeout vs debounce

文章目录

先给结论

setTimeout / debounce = 时间层面的延迟

startTransition = UI 优先级 & 可中断调度

它们解决的是 完全不同的问题。

先给一张总对照表

维度 setTimeout debounce startTransition
本质 JS 定时器 JS 定时策略 React 调度语义
是否理解 UI ❌ ❌ ✅
是否可中断 ❌ ❌ ✅
是否降低计算次数 ❌ ✅ ❌
是否防抖 ❌ ✅ ❌
是否解决卡输入 ❌ ⚠️ 部分 ✅
React 推荐 ❌ ⚠️ ✅

一、setTimeout:只是"往后丢一会儿"

代码

ts 复制代码
setTimeout(() => {
  setList(filter(data))
}, 0)

实际发生了什么?

  • 把任务放进 macrotask queue
  • 当前 call stack 执行完再跑
  • 但一旦开始执行,就不能被打断

为什么不能解决卡顿?

复制代码
输入
↓
JS 空闲
↓
setTimeout callback 开始
↓
filter(data) 占满 500ms
↓
输入仍然卡

它只是换了个时间点卡你

什么时候还能用?

  • 非 UI 逻辑
  • 低优先级副作用
  • 日志 / 打点

二、debounce:减少执行次数,不是调度

代码

ts 复制代码
const debouncedFilter = debounce((v) => {
  setList(filter(data, v))
}, 300)

它解决的是什么?

"你别每次都算"

  • 用户输入 10 次
  • debounce 后只算 1 次

它没解决什么?

  • 一旦真的执行
  • filter(data) 仍然是同步的
  • 仍然会卡主线程

debounce = 减少次数,不是让 UI 优先

debounce 的适用场景

场景 是否合适
请求接口 ✅
自动保存 ✅
搜索接口 ✅
本地大计算 ❌

三、startTransition:React 级别的"让路"

代码

ts 复制代码
startTransition(() => {
  setList(filter(data))
})

它到底做了什么?

React 在内部标记:

"这次更新可以被打断"

然后:

  • 输入事件 → 高优先级
  • transition 更新 → 低优先级
  • React 在空闲时间切片执行

时间线对比(非常关键)

setTimeout / debounce

复制代码
filter 开始
↓
500ms 主线程占满
↓
输入卡

startTransition

复制代码
filter 执行一部分
↓
用户输入
↓
React 中断 filter
↓
更新 input
↓
继续 filter

这是本质差异。

四、三者最容易搞混的一点

startTransition 不会减少计算量

ts 复制代码
filter(data) // 还是会算

它只是:

  • 不一次性算完
  • 不阻塞 urgent 更新

五、正确的组合方式(生产级)

debounce + startTransition(最强)

ts 复制代码
const onChange = debounce((value) => {
  startTransition(() => {
    setList(filter(data, value))
  })
}, 200)

既少算,又不卡

错误组合(常见)

ts 复制代码
startTransition(() => {
  debounce(() => setList(...), 300)()
})

完全没意义。

六、一个表格搜索的真实决策树

输入 → 表格过滤 → 10000 行

问题 答案
每次输入都要算吗? ❌
能不能晚点算? ✅
用户在 input 框输入必须立即显示文字吗? ✅

debounce + startTransition

七、为什么 React 团队不推荐 setTimeout?

因为:

  • 它绕过 React Scheduler
  • React 无法协调更新
  • 在 Concurrent 模式下是"黑盒"

八、用一句工程化标准帮你记住

JS 时间工具(setTimeout / debounce)

管"什么时候执行"

React 工具(startTransition)

管"谁先执行"

九、最后一段"刻进脑子"的话

setTimeout:

"等会再卡你"

debounce:

"少卡几次"

startTransition:

"先让用户动起来"

相关推荐
QianhangQianping10 分钟前
撤销重做不是「存快照」:一个可视化编辑器的Operation 设计
java·前端·数据库·typescript·编辑器·前端架构·撤销重做
Nymph_Zhu1 小时前
pdf转换markdown预览及内容互相点击定位
前端·pdf·vue3·markdown·element-plus
计算机魔术师1 小时前
Google 一天蒸发5000亿,Reddit 靠 AI 训练喂得饱自己却饿死
前端
小大宇1 小时前
Vue知识点-ElementPlus-05 输入框
前端·javascript·vue.js
l1m0_1 小时前
AI设计工具有哪些?Paico、Pixso AI、墨刀AI、Lovable、Codex怎么选
前端·人工智能·ai·设计·墨刀·codex·pixso
web打印社区2 小时前
Lodop在Edge和双核浏览器-先分清内核
前端·javascript·edge·pdf·ecmascript·html5
西瓜拿铁好喝2 小时前
开源和闭源 AI 办公工具,分别适合谁
java·前端·数据库
IT_陈寒2 小时前
深入理解SpringBoot:核心原理与最佳实践
前端·人工智能·后端
风骏时光牛马2 小时前
大模型综合能力多维评测:性能、逻辑与落地表现对比
前端
liuchangng2 小时前
React 19 + Vite 6 实战:从教材 PDF 到 866 词间隔重复单词 App
前端·react.js·pdf·vite·开源项目