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:

"先让用户动起来"

相关推荐
gyratesky11 分钟前
记录一种很新的大屏开发方式
前端·数据可视化
xy34531 小时前
Axure 9.0 中继器核心结构
前端·ui·html·axure·原型·产品设计
老王以为1 小时前
走进 AI Agent 第四篇(上):知识获取管道——RAG 基础
前端·人工智能·全栈
夏天要喝冰可乐1 小时前
一处写作,多平台分发:我给掘金做了一款开源 Chrome 插件
前端·chrome·vibecoding
货拉拉技术2 小时前
货拉拉开源Hadice:安卓 & 鸿蒙桌面调试工具
前端
程序猿DD2 小时前
OctaFuse Gateway 2.11.0:流式请求优化、用户折扣策略与错误契约升级
前端·后端
尾善爱看海2 小时前
《JavaScript 数组操作全攻略:12 类 API + 30 个实战场景 + 20 个避坑指南》
前端·javascript·面试
计算机魔术师3 小时前
Anthropic 估值冲 4 万亿,但企业客户已经偷偷换了便宜模型
前端
王六米。3 小时前
RAG知识库建设 文档解析 切分与索引如何衔接
服务器·前端·网络·企业数字化转型·智钳智能盒子