核心是按执行时间切片长任务,每片控制在10–30ms内,用宏任务(如setTimeout或requestIdleCallback)主动让出主线程;以performance.now()实测耗时而非固定数量为切片依据,结合deadline.timeRemaining()动态调整单次处理量,并用DocumentFragment等减少DOM干扰。

核心是把长任务按执行时间切片,每片控制在 10–30ms 内,用宏任务(如 setTimeout 或 requestIdleCallback)主动交出主线程,让浏览器有机会渲染、响应输入。
用时间而非数量做切片依据
固定处理 100 条数据不可靠——高端机可能只用 2ms,低端机却超 50ms。应以实际耗时为准:
- 每次切片前记录
performance.now()起始时间 - 循环中每处理若干项(比如 5–10 个)就检查已用时:
performance.now() - start > 10 - 一旦接近 10–12ms 安全窗口,立即中断,用
setTimeout(() => next(), 0)推入下一帧
优先选用 requestIdleCallback 动态控时
它提供真实空闲时间,比 setTimeout(, 0) 更精准:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- 回调中接收
deadline,调用deadline.timeRemaining() > 4判断是否继续 - 配合
{ timeout: 32 }防止任务被无限搁置 - 若
timeRemaining()持续偏低(如常<3ms),自动缩小单次处理量(如从 20 项降到 5 项)
宏任务是让权的关键锚点
只有宏任务能真正释放渲染权,微任务不行:
-
setTimeout和setImmediate是最稳妥的切片边界,适合主流程分段 -
queueMicrotask只能在单个切片内部快速串行轻量操作(如校验→格式化→暂存),不能替代宏任务让出主线程 - 避免用
Promise.then链式切片——错误未捕获易中断流程,且调度不可控
配套减少 DOM 干扰,提升切片效率
即使切片了,频繁 DOM 操作仍会触发强制重排,抵消切片效果:
- 用
DocumentFragment批量构建节点,最后一次性挂载 - 避免在切片中反复读写
offsetTop、getBoundingClientRect()等触发同步布局的属性 - 对日历、列表等场景,先占位空容器,再异步填充内容,跨日连线类逻辑延迟到所有相关节点挂载后再统一计算

















