笔记来源:小满zs
虚拟 DOM
// react.js
// jsx => babel | swc => React.createElement
const React = {
createElement(type, props, ...children) {
return {
type,
props: {
...props,
children: children.map(child => typeof child === 'object' ? child : React.createTextElement(child))
}
}
},
createTextElement(text) {
return {
type: 'TEXT_ELEMENT',
props: {
nodeValue: text,
children: []
}
}
},
}
// 测试 vDOM
const vDOM = React.createElement('div', { id: 'foo' }, React.createElement('span', null, 'bar'))
console.log("=>(react.js:24) vDOM", vDOM);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="root"></div>
<script src="./react.js"></script>
</body>
</html>
任务切片
浏览器一帧为60FPS,也就是16ms(1000毫秒/60帧≈16.67毫秒)。
浏览器一帧完成的任务:
- 处理事件的回调click.…事件
- 处理计时器的回调
- 开始帧
- 执行 requestAnimationFrame 动画的回调
- 计算机页面布局计算(DOM)合并到主线程
- 绘制
- 如果此时还有空闲时间,执行 requestldleCallback(React 使用了该函数的思想,React 自己又实现了 requestldleCallback)
// 完成虚拟 DOM 转 fiber 结构和时间切片
let nextUnitOfWork = null
function workLoop(deadline) {
let shouldYield = false
while (nextUnitOfWork && !shouldYield) {
nextUnitOfWork = performUnitOfWork(nextUnitOfWork)
shouldYield = deadline.timeRemaining() < 1
}
requestIdleCallback(workLoop)
}
requestIdleCallback(workLoop)
function performUnitOfWork() {
}
对任务切片可以简单理解为 将所有的任务分成一个一个小任务,这里小任务函数都放在 requestIdleCallback 中,先执行优先级高的小任务,每一帧执行一个小任务,直到将所有小任务执行完毕。
待完成~