返回动态
2 分钟阅读

原生“时间切片”能力,提升浏览器响应性

在复杂交互页面开发中,JavaScript 执行耗时较长的任务会导致浏览器响应用户输入的能力变慢,从而影响用户体验。为了解决这个问题,Chrome 129 引入了 scheduler.yield() 方法,允许开发者将耗时任务分解为较小的任务块,从而提高页面的响应能力。早在 Chrome 115 版本,其开始了对 scheduler.yield 的灰度测试。

工作原理

scheduler.yield() 的主要作用是告诉浏览器:“我即将要做的工作可能需要很长时间,如果你需要渲染页面、响应用户输入或有其他更重要的任务,没关系,我可以等你们做完再继续!”。

image

image

示例代码:

async function validateForm() {
  return new Promise(resolve => setTimeout(resolve, 500));
}
async function showSpinner() {
  return new Promise(resolve => setTimeout(resolve, 500));
}
async function saveToDatabase() {
  return new Promise(resolve => setTimeout(resolve, 500));
}
async function updateUI() {
  return new Promise(resolve => setTimeout(resolve, 500));
}
async function sendAnalytics() {
  return new Promise(resolve => setTimeout(resolve, 500));
}
async function saveSettings() {
  const tasks = [
    validateForm,
    showSpinner,
    saveToDatabase,
    updateUI,
    sendAnalytics,
  ];
  while (tasks.length > 0) {
    const task = tasks.shift();
    await task();
    console.log(`${task.name} 已运行`);
    await scheduler.yield();
  }
}

在这个示例中,saveSettings 函数将一系列耗时任务分解为较小的块,并在每个任务之间调用 scheduler.yield(),以确保主线程保持响应性。

优势

scheduler.yield() 的主要优势在于其延续性。这意味着在一组任务中,如果你使用 yield 暂停执行,其他已安排的任务将在 yield 点后继续按顺序执行。这可以避免第三方脚本的代码打乱你代码执行的顺序。

替代方案

如果 scheduler.yield() 不可用,可以使用 scheduler.postTask() 并设定 priority: 'user-blocking' 作为替代方案。这种高优先级会让任务尽快执行,减少中断。

总结

scheduler.yield() 为浏览器提供了原生的时间切片能力,使开发者能够更好地控制任务执行的优先级和时机。通过将耗时任务分解成较小的块,并在适当的时候让出主线程,可以显著提升页面的响应性和用户体验。这种新的 API 不仅简化了任务调度的实现,还为构建更流畅的 Web 应用提供了坚实的基础。

评论