目标:实现任务调度器
为什么要实现任务调度器
- dom特别大的时候会造成渲染卡顿
-
看一个demo,代码如下,卡顿原因,js执行是单线程的,while循环逻辑会阻塞后面渲染
- main.js
const el = document.createElement("div"); el.innerHTML = "I love eat cakes"; document.body.appendChild(el); let i = 0 while (i < 100000000000) { i++ }- index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Demo</title> </head> <body> <script type="module" src="main.js"></script> </body> </html>
之前写的render函数其实也是一个道理
- 是一个递归,如果树非常大就会一直render
如何解决
- 使用分治的思想去拆分,比如一个任务只渲染两个dom树,直 到渲染结束
-
借助浏览器的
requestIdleCallbackApi实现,新建index.js并在index.html中引入- index.js,这个功能整个就叫做任务调度器
let taskId = 1
function workLoop (deadline) {
taskId ++
console.log(deadline.timeRemaining())
let shouldYield = false
while (!shouldYield) {
// 之后把渲染任务放到这里来执行
console.log(`runt task ${taskId}`)
shouldYield = deadline.timeRemaining() < 1
}
requestIdleCallback(workLoop)
}
requestIdleCallback(workLoop)
剩余问题: 之前是一口气把一整个dom树渲染出来
- 如何把渲染把它分配到每一个任务控制渲染,我们将在后续小节中实现