Match-id-3d913d35f0eb68f4d311fcf073625132167ca7b4

This commit is contained in:
* 2022-11-01 20:12:47 +08:00 committed by *
parent cbd821aed3
commit ed2f6e8df5
2 changed files with 39 additions and 46 deletions

View File

@ -86,7 +86,7 @@ function collectDirtyNodes(vNode: VNode, parent: VNode): void {
if (parent.dirtyNodes === null) { if (parent.dirtyNodes === null) {
parent.dirtyNodes = dirtyNodes; parent.dirtyNodes = dirtyNodes;
} else { } else {
parent.dirtyNodes.push(...vNode.dirtyNodes); parent.dirtyNodes.push(...dirtyNodes);
dirtyNodes.length = 0; dirtyNodes.length = 0;
} }
vNode.dirtyNodes = null; vNode.dirtyNodes = null;
@ -105,7 +105,7 @@ function collectDirtyNodes(vNode: VNode, parent: VNode): void {
// 尝试完成当前工作单元然后移动到下一个兄弟工作单元。如果没有更多的同级请返回父vNode。 // 尝试完成当前工作单元然后移动到下一个兄弟工作单元。如果没有更多的同级请返回父vNode。
function bubbleVNode(vNode: VNode): void { function bubbleVNode(vNode: VNode): void {
let node = vNode; let node : VNode | null = vNode;
do { do {
const parent = node.parent; const parent = node.parent;
@ -182,14 +182,18 @@ function isEqualByIndex(idx: number, pathArrays: string[][]) {
function getChildByIndex(vNode: VNode, idx: number) { function getChildByIndex(vNode: VNode, idx: number) {
let node = vNode.child; let node = vNode.child;
for (let i = 0; i < idx; i++) { for (let i = 0; i < idx; i++) {
node = node.next; if (node) {
node = node.next;
} else {
return null;
}
} }
return node; return node;
} }
// 从多个更新节点中,计算出开始节点。即:找到最近的共同的父辈节点 // 从多个更新节点中,计算出开始节点。即:找到最近的共同的父辈节点
export function calcStartUpdateVNode(treeRoot: VNode) { export function calcStartUpdateVNode(treeRoot: VNode) {
const toUpdateNodes = Array.from(treeRoot.toUpdateNodes); const toUpdateNodes = Array.from(treeRoot.toUpdateNodes!);
if (toUpdateNodes.length === 0) { if (toUpdateNodes.length === 0) {
return treeRoot; return treeRoot;
@ -218,12 +222,12 @@ export function calcStartUpdateVNode(treeRoot: VNode) {
// 得到相等的路径 // 得到相等的路径
const startNodePath = pathArrays[0].slice(0, commonPathEndIndex); const startNodePath = pathArrays[0].slice(0, commonPathEndIndex);
let node = treeRoot; let node: VNode | null = treeRoot;
for (let i = 1; i < startNodePath.length; i++) { for (let i = 1; i < startNodePath.length; i++) {
const pathIndex = Number(startNodePath[i]); const pathIndex = Number(startNodePath[i]);
node = getChildByIndex(node, pathIndex)!; node = getChildByIndex(node, pathIndex);
// 路径错误时,回退到从根更新 // 路径错误时,回退到从根更新
if (node == null) { if (node === null) {
return treeRoot; return treeRoot;
} }
} }
@ -242,7 +246,7 @@ function buildVNodeTree(treeRoot: VNode) {
setStartVNode(startVNode); setStartVNode(startVNode);
// 清空toUpdateNodes // 清空toUpdateNodes
treeRoot.toUpdateNodes.clear(); treeRoot.toUpdateNodes!.clear();
if (startVNode.tag !== TreeRoot) { // 不是根节点 if (startVNode.tag !== TreeRoot) { // 不是根节点
// 设置namespace用于createElement // 设置namespace用于createElement

View File

@ -24,13 +24,7 @@ import {
createPortalVNode, createPortalVNode,
createDomTextVNode, createDomTextVNode,
} from '../vnode/VNodeCreator'; } from '../vnode/VNodeCreator';
import { import { isSameType, getIteratorFn, isTextType, isIteratorType, isObjectType } from './DiffTools';
isSameType,
getIteratorFn,
isTextType,
isIteratorType,
isObjectType,
} from './DiffTools';
import { travelChildren } from '../vnode/VNodeUtils'; import { travelChildren } from '../vnode/VNodeUtils';
import { markVNodePath } from '../utils/vNodePath'; import { markVNodePath } from '../utils/vNodePath';
@ -120,10 +114,12 @@ function getNodeType(newChild: any): string | null {
function setVNodeAdditionFlag(newNode: VNode, lastPosition: number): number { function setVNodeAdditionFlag(newNode: VNode, lastPosition: number): number {
let position = lastPosition; let position = lastPosition;
if (newNode.isCreated || newNode.eIndex < lastPosition) { // 位置 小于 上一个复用的位置 if (newNode.isCreated || newNode.eIndex < lastPosition) {
// 位置 小于 上一个复用的位置
// 标记为新增 // 标记为新增
FlagUtils.setAddition(newNode); FlagUtils.setAddition(newNode);
} else { // 复用 } else {
// 复用
position = newNode.eIndex; position = newNode.eIndex;
} }
@ -206,15 +202,16 @@ function transRightChildrenToArray(child) {
return rightChildrenArray; return rightChildrenArray;
} }
function transLeftChildrenToMap( function transLeftChildrenToMap(startChild: VNode, rightEndVNode: VNode | null): Map<string | number, VNode> {
startChild: VNode,
rightEndVNode: VNode | null,
): Map<string | number, VNode> {
const leftChildrenMap: Map<string | number, VNode> = new Map(); const leftChildrenMap: Map<string | number, VNode> = new Map();
travelChildren(startChild, node => { travelChildren(
leftChildrenMap.set(node.key !== null ? node.key : node.eIndex, node); startChild,
}, node => node === rightEndVNode); node => {
leftChildrenMap.set(node.key !== null ? node.key : node.eIndex, node);
},
node => node === rightEndVNode
);
return leftChildrenMap; return leftChildrenMap;
} }
@ -235,11 +232,7 @@ function getOldNodeFromMap(nodeMap: Map<string | number, VNode>, newIdx: number,
} }
// diff数组类型的节点核心算法 // diff数组类型的节点核心算法
function diffArrayNodesHandler( function diffArrayNodesHandler(parentNode: VNode, firstChild: VNode | null, newChildren: Array<any>): VNode | null {
parentNode: VNode,
firstChild: VNode | null,
newChildren: Array<any>,
): VNode | null {
let resultingFirstChild: VNode | null = null; let resultingFirstChild: VNode | null = null;
let prevNewNode: VNode | null = null; let prevNewNode: VNode | null = null;
@ -358,7 +351,7 @@ function diffArrayNodesHandler(
if (rightNewNode) { if (rightNewNode) {
appendNode(rightNewNode); appendNode(rightNewNode);
setVNodesCIndex(rightNewNode, prevNewNode.cIndex + 1); setVNodesCIndex(rightNewNode, rightNewNode.cIndex + 1);
} }
return resultingFirstChild; return resultingFirstChild;
@ -366,13 +359,14 @@ function diffArrayNodesHandler(
// 4. 新节点还有一部分,但是老节点已经没有了 // 4. 新节点还有一部分,但是老节点已经没有了
if (oldNode === null) { if (oldNode === null) {
let isDirectAdd = false; let isDirectAdd = false;
// TODO: 是否可以扩大至非dom类型节点 // TODO: 是否可以扩大至非dom类型节点
// 如果dom节点在上次添加前没有节点说明本次添加时可以直接添加到最后不需要通过 getSiblingDom 函数找到 before 节点 // 如果dom节点在上次添加前没有节点说明本次添加时可以直接添加到最后不需要通过 getSiblingDom 函数找到 before 节点
if (parentNode.tag === DomComponent && if (
parentNode.tag === DomComponent &&
parentNode.oldProps?.children?.length === 0 && parentNode.oldProps?.children?.length === 0 &&
rightIdx - leftIdx === newChildren.length) { rightIdx - leftIdx === newChildren.length
) {
isDirectAdd = true; isDirectAdd = true;
} }
const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated; const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated;
@ -424,7 +418,8 @@ function diffArrayNodesHandler(
const eIndex = newNode.eIndex; const eIndex = newNode.eIndex;
eIndexes.push(eIndex); eIndexes.push(eIndex);
last = eIndexes[result[result.length - 1]]; last = eIndexes[result[result.length - 1]];
if (eIndex > last || last === undefined) { // 大的 eIndex直接放在最后 if (eIndex > last || last === undefined) {
// 大的 eIndex直接放在最后
preIndex[i] = result[result.length - 1]; preIndex[i] = result[result.length - 1];
result.push(i); result.push(i);
} else { } else {
@ -500,13 +495,13 @@ function setVNodesCIndex(startChild: VNode | null, startIdx: number) {
function diffIteratorNodesHandler( function diffIteratorNodesHandler(
parentNode: VNode, parentNode: VNode,
firstChild: VNode | null, firstChild: VNode | null,
newChildrenIterable: Iterable<any>, newChildrenIterable: Iterable<any>
): VNode | null { ): VNode | null {
const iteratorFn = getIteratorFn(newChildrenIterable); const iteratorFn = getIteratorFn(newChildrenIterable);
const iteratorObj = iteratorFn.call(newChildrenIterable); const iteratorObj: Iterator<any> = iteratorFn.call(newChildrenIterable);
// 把iterator转测数组 // 把iterator转测数组
const childrenArray = []; const childrenArray: any[] = [];
let result = iteratorObj.next(); let result = iteratorObj.next();
while (!result.done) { while (!result.done) {
childrenArray.push(result.value); childrenArray.push(result.value);
@ -517,12 +512,7 @@ function diffIteratorNodesHandler(
} }
// 新节点是字符串类型 // 新节点是字符串类型
function diffStringNodeHandler( function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode: VNode | null, isComparing: boolean) {
parentNode: VNode,
newChild: any,
firstChildVNode: VNode,
isComparing: boolean
) {
let newTextNode: VNode | null = null; let newTextNode: VNode | null = null;
// 第一个vNode是Text则复用 // 第一个vNode是Text则复用
@ -550,7 +540,6 @@ function diffObjectNodeHandler(
parentNode: VNode, parentNode: VNode,
firstChild: VNode | null, firstChild: VNode | null,
newChild: any, newChild: any,
firstChildVNode: VNode,
isComparing: boolean isComparing: boolean
) { ) {
let canReuseNode: VNode | null = null; let canReuseNode: VNode | null = null;
@ -569,7 +558,7 @@ function diffObjectNodeHandler(
} }
let resultNode: VNode | null = null; let resultNode: VNode | null = null;
let startDelVNode = firstChildVNode; let startDelVNode: VNode | null = firstChild;
if (newChild.vtype === TYPE_COMMON_ELEMENT) { if (newChild.vtype === TYPE_COMMON_ELEMENT) {
if (canReuseNode) { if (canReuseNode) {
// 可以复用 // 可以复用
@ -664,7 +653,7 @@ export function createChildrenByDiff(
// 5. newChild是对象类型 // 5. newChild是对象类型
if (isObjectType(newChild)) { if (isObjectType(newChild)) {
const newVNodes = diffObjectNodeHandler(parentNode, firstChild, newChild, firstChild, isComparing); const newVNodes = diffObjectNodeHandler(parentNode, firstChild, newChild, isComparing);
if (newVNodes) { if (newVNodes) {
return newVNodes; return newVNodes;
} }