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:

"先让用户动起来"

相关推荐
绝美焦栖2 小时前
低版本pdfjs升级
前端·javascript·vue.js
阿里巴巴终端技术2 小时前
二十年,重新出发!第 20 届 D2 技术大会「AI 新」议题全球征集正式开启
前端·react.js·html
阿祖zu2 小时前
2025 AI 总结:技术研发的技能升维与职业路径系统重构的思考
前端·后端·ai编程
IT_陈寒2 小时前
Vite 5分钟性能优化实战:从3秒到300ms的冷启动提速技巧(附可复用配置)
前端·人工智能·后端
迦南giser2 小时前
webpack从0到1详解
前端·javascript·css·webpack·node.js
xkxnq2 小时前
第二阶段:Vue 组件化开发(第 26天)
前端·javascript·vue.js
华玥作者2 小时前
uni-app + Vite 项目中使用 @uni-helper/vite-plugin-uni-pages 实现自动路由配置(超详细)
前端·uni-app·vue·vue3·vite
m0_748254662 小时前
HTML 文本格式化基础
前端·html
十六年开源服务商2 小时前
WordPress集成GoogleAnalytics最佳实践指南
前端·人工智能·机器学习