与长任务分手或:我如何学会分组循环并使用 yield

主要观点:数组遍历方式不当会导致同步处理大量数据,形成长任务影响用户体验,需优化交互响应。
关键信息

  • 简单for..of循环和forEach等数组方法默认同步处理,易形成长任务。
  • 长任务会导致用户交互延迟和慢交互性能,影响用户体验和业务指标。
  • 中断任务让事件循环继续的方式有setTimeout(延迟 0ms)和scheduler.yield,使用 async/await 使循环异步,但forEach等方法不会等待yield
  • for..of循环中每次迭代yield效果好,但setTimeout会有较大时间差异,可通过批处理优化总处理时间。
  • 批处理可按处理时间而非数量进行,需权衡用户等待时间和总处理时间。
  • 考虑帧速率,scheduler.yield有优先处理权,可通过调整批处理时长和requestAnimationFrame来优化平滑度,同时处理页面隐藏等边缘情况。
    重要细节
  • 如 CPU 完成一个单位工作需 0.25ms,1000 个单位则总处理时间 250ms 形成长任务。
  • forEach方法会忽略异步回调函数,继续处理数组项。
  • reduce方法虽可异步处理,但仍同步排队微任务。
  • 不同浏览器对scheduler.yieldsetTimeout的处理方式不同,嵌套setTimeout有 4ms 间隙。
  • 通过performance.mark可自定义时间标记requestAnimationFrame回调运行。
  • 可根据应用需求调整批处理时长和yield策略,以平衡用户体验和处理效率。
阅读 5
0 条评论