1.Vue 的 vdom和Diff
1.1. Vue 的实现:
// Vue 2.x 的 VNode 结构
{
tag: 'div', // 标签名
data: { // 节点数据
class: 'container',
attrs: { id: 'app' },
on: { click: handler }
},
children: [], // 子节点
text: undefined, // 文本内容
elm: undefined, // 对应的真实 DOM 节点
context: vm, // Vue 实例
key: undefined // 节点的 key 属性
}
// Vue 3.x 的优化
const vnode = {
type: 'div',
props: { class: 'container' },
children: [],
component: null,
key: null,
shapeFlag: ShapeFlags.ELEMENT
}
1.2.Vue 的 Diff 算法特点:
// 四个指针
let oldStartIdx = 0
let oldEndIdx = oldChildren.length - 1
let newStartIdx = 0
let newEndIdx = newChildren.length - 1
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
if (sameVnode(oldStartVnode, newStartVnode)) {
// 头部节点相同
patchVnode(oldStartVnode, newStartVnode)
} else if (sameVnode(oldEndVnode, newEndVnode)) {
// 尾部节点相同
patchVnode(oldEndVnode, newEndVnode)
} else if (sameVnode(oldStartVnode, newEndVnode)) {
// 旧头新尾
patchVnode(oldStartVnode, newEndVnode)
// 移动节点
} else if (sameVnode(oldEndVnode, newStartVnode)) {
// 旧尾新头
patchVnode(oldEndVnode, newStartVnode)
// 移动节点
} else {
// 查找、移动或创建节点
}
}
1.3 Vue 3 的优化:
// 静态标记
const hoisted = createVNode('div', null, 'static content')
function render() {
return hoisted
}
// Fragments
const Fragment = Symbol('Fragment')
const fragment = {
type: Fragment,
children: []
}
2.React 的Vdom和Diff
2.1 React 的实现:
// React 的 VDOM 结构
{
type: 'div',
props: {
className: 'container',
children: []
},
key: null,
ref: null,
$$typeof: Symbol.for('react.element')
}
// Fiber 节点结构
{
type: 'div',
key: null,
stateNode: HTMLDivElement,
child: FiberNode,
sibling: FiberNode,
return: FiberNode,
pendingProps: {},
memoizedProps: {},
updateQueue: []
}
2.2 React 的 Diff 算法特点:单向遍历
function reconcileChildrenArray(
returnFiber: Fiber,
currentFirstChild: Fiber | null,
newChildren: Array<any>
) {
let oldFiber = currentFirstChild;
let newIdx = 0;
let previousNewFiber = null;
// 第一轮:处理更新的节点
for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
if (oldFiber.index > newIdx) {
nextOldFiber = oldFiber;
oldFiber = null;
} else {
nextOldFiber = oldFiber.sibling;
}
const newFiber = updateSlot(
returnFiber,
oldFiber,
newChildren[newIdx]
);
if (newFiber === null) {
break;
}
// ... 处理更新
}
// 第二轮:处理剩余节点
if (newIdx === newChildren.length) {
// 删除剩余旧节点
deleteRemainingChildren(returnFiber, oldFiber);
return resultingFirstChild;
}
if (oldFiber === null) {
// 添加剩余新节点
for (; newIdx < newChildren.length; newIdx++) {
const newFiber = createChild(
returnFiber,
newChildren[newIdx]
);
// ... 处理新建
}
}
}
3.Vue vs React 对比:
3.1:性能优化策略:
// Vue
// 1. 静态节点提升
const staticNode = createVNode('div', null, 'static')
// 2. 响应式系统优化
const state = reactive({
count: 0
})
// React
// 1. memo 优化
const MemoComponent = React.memo(({ value }) => {
return <div>{value}</div>
})
// 2. useMemo 优化
const memoizedValue = useMemo(() => computeValue(a, b), [a, b])
3.2 主要区别:
- 更新粒度:
- Vue:基于响应式系统,可以精确追踪组件的依赖关系
- React:自顶向下的递归比较,需要手动优化
- Diff 算法:
- Vue:双端比较 + 最长递增子序列
- React:单向遍历 + Fiber 架构
- 静态优化:
- Vue:编译时优化,静态提升
- React:运行时优化,手动 memo
- 更新机制:
- Vue:响应式触发,异步更新队列
- React:setState 触发,Fiber 调度
- 性能优化:
- Vue:自动依赖收集,编译优化
- React:手动优化,memo/useMemo/useCallback
选择建议:
需要精确更新:选择 Vue
需要灵活控制:选择 React
- 小型应用:Vue 更简单
- 大型应用:两者都可以
这就是 Vue 和 React 在 Virtual DOM 和 Diff 算法上的主要区别。两者都有其优势,选择哪个主要取决于具体需求和团队情况。
标签:Vue,const,newIdx,React,oldFiber,Vue2,Vue3,null From: https://blog.csdn.net/m0_73574455/article/details/144674210