# 怎么优化长任务

# 前提

  1. 浏览器主线程在执行完一个完整的js任务,才会去执行下一个
  2. performance 可以看到有哪些长任务

# 任务管理策略

# 拆分伪多个小任务

function saveSettings () {
   validateForm();
   showSpinner();
   saveToDatabase();
   updateUI();
   sendAnalytics();
}
1
2
3
4
5
6
7

# 用异步操作延迟任务执行

  1. setTimeout(()=>{},0);
  2. async + setTimeout
function yieldToMain () {
  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}
1
2
3
4
5

# 使用 requestIdleCallback

  1. 有可能会导致永远执行不到

# 只在用户操作的时候让步

  1. isInputPending
async function saveSettings () {
  // 函数队列
  const tasks = [validateForm,showSpinner,saveToDatabase,updateUI,sendAnalytics  ];
  
  while (tasks.length > 0) {
    // 让步于用户输入
    if (navigator.scheduling.isInputPending()) {
      // 如果有用户输入在等待,则让步
      await yieldToMain();
    } else {
      // Shift the the task out of the queue:
      const task = tasks.shift();

      // Run the task:
      task();
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# postTask

  1. 兼容性差,safari 完全不支持
  2. postTask并不是所有浏览器都支持。可以检测是否空,或者考虑使用polyfill。

# 使用web worker

  1. 主要用在计数型的需求,计算完成回传浏览器
Last Updated: 6/3/2024, 1:08:34 AM