React的重要原理
虚拟 DOM
首先先看一下虚拟 dom 虚拟 dom 就是使用 Javascript 对象去描述一个 DOM 结构,虚拟 DOM 不是直接操作浏览器的真实 DOM,而是首先对 UI 的更新在虚拟 DOM 上进行,然后再高效地同步到真实的 DOM 上
优点 性能的优化,涉及大量节点的更新的时候虚拟 DOM 可以去减少不必要的 DOM 操作,主要体现在 Diff 算法的复用操作,但实际上也提高不了多少性能 跨平台性 虚拟 DOM 是一个与平台没有关系的概念可以映射到不同的渲染目标
实现简易的虚拟 DOM
平时我们在写 react 组件的时候会这样写
const App = () => {
return <div>hello world</div>;
};
上面的这段代码可以被 babel 转化为
const App = () => {
return React.createElement("div", null, "hello world");
};
JSX 通过 babel 或者其他工具 转化为 js 然后使用 createElement 方法来传递标签名称 props 和 child 元素
接下来来实现 React.createElement 方法
实现 createElement 方法
React.createElement 是用于实现虚拟的 DOM 树,通过返回一个包含 type 和 props 的对象,type 是元素类型,props 是属性和子元素 children 可以是其他的虚拟 DOM 对象 createTextElement 是用来处理文本节点的,因为我们平时会写这样的 JSX 代码
const App = () => {
return <div>hello world</div>;
};
这里面的 hello world 就是文本节点,所以我们需要处理文本节点
const React = {
createElement(type, props, ...children) {
return {
type,
props: {
...props,
children: children.map((child) => {
if (typeof child === "object") {
return child;
} else {
return React.createElement(child);
}
}),
},
};
},
createTextElement(text) {
return {
type: "TEXT_ELEMENT",
props: {
nodeValue: text,
children: [],
},
};
},
};
// const text = document.createTextNode('');
// text.nodeValue = 'hello world';
但是上面的有一个问题,如果渲染的过多,就需要等待,但是 React 有一个类似于浏览器钟的机制,就是 requestIdleCallback, 这个方法会在浏览器空闲的时候执行,所以我们可以使用这个方法来实现渲染
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(nextUnitOfWork) {}
React fiber
react Fiber 是 react16 中引入的一种新的协调引擎,用于解决和优化 react 应对复杂 Ui 的性能问题
fiber 有两个树,一个是当前的工作树,一个是之前的树,这样可以在两个树之间进行比较,然后找出需要更新的节点,然后进行更新