From ed2f6e8df5a2c992186ab77cc127bb52dceeab59 Mon Sep 17 00:00:00 2001 From: * <8> Date: Tue, 1 Nov 2022 20:12:47 +0800 Subject: [PATCH] Match-id-3d913d35f0eb68f4d311fcf073625132167ca7b4 --- libs/horizon/src/renderer/TreeBuilder.ts | 20 +++--- .../src/renderer/diff/nodeDiffComparator.ts | 65 ++++++++----------- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index 71dd01e0..4e1e864d 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -86,7 +86,7 @@ function collectDirtyNodes(vNode: VNode, parent: VNode): void { if (parent.dirtyNodes === null) { parent.dirtyNodes = dirtyNodes; } else { - parent.dirtyNodes.push(...vNode.dirtyNodes); + parent.dirtyNodes.push(...dirtyNodes); dirtyNodes.length = 0; } vNode.dirtyNodes = null; @@ -105,7 +105,7 @@ function collectDirtyNodes(vNode: VNode, parent: VNode): void { // 尝试完成当前工作单元,然后移动到下一个兄弟工作单元。如果没有更多的同级,请返回父vNode。 function bubbleVNode(vNode: VNode): void { - let node = vNode; + let node : VNode | null = vNode; do { const parent = node.parent; @@ -182,14 +182,18 @@ function isEqualByIndex(idx: number, pathArrays: string[][]) { function getChildByIndex(vNode: VNode, idx: number) { let node = vNode.child; for (let i = 0; i < idx; i++) { - node = node.next; + if (node) { + node = node.next; + } else { + return null; + } } return node; } // 从多个更新节点中,计算出开始节点。即:找到最近的共同的父辈节点 export function calcStartUpdateVNode(treeRoot: VNode) { - const toUpdateNodes = Array.from(treeRoot.toUpdateNodes); + const toUpdateNodes = Array.from(treeRoot.toUpdateNodes!); if (toUpdateNodes.length === 0) { return treeRoot; @@ -218,12 +222,12 @@ export function calcStartUpdateVNode(treeRoot: VNode) { // 得到相等的路径 const startNodePath = pathArrays[0].slice(0, commonPathEndIndex); - let node = treeRoot; + let node: VNode | null = treeRoot; for (let i = 1; i < startNodePath.length; i++) { const pathIndex = Number(startNodePath[i]); - node = getChildByIndex(node, pathIndex)!; + node = getChildByIndex(node, pathIndex); // 路径错误时,回退到从根更新 - if (node == null) { + if (node === null) { return treeRoot; } } @@ -242,7 +246,7 @@ function buildVNodeTree(treeRoot: VNode) { setStartVNode(startVNode); // 清空toUpdateNodes - treeRoot.toUpdateNodes.clear(); + treeRoot.toUpdateNodes!.clear(); if (startVNode.tag !== TreeRoot) { // 不是根节点 // 设置namespace,用于createElement diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts index 3899dae9..4186d361 100644 --- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts +++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts @@ -24,13 +24,7 @@ import { createPortalVNode, createDomTextVNode, } from '../vnode/VNodeCreator'; -import { - isSameType, - getIteratorFn, - isTextType, - isIteratorType, - isObjectType, -} from './DiffTools'; +import { isSameType, getIteratorFn, isTextType, isIteratorType, isObjectType } from './DiffTools'; import { travelChildren } from '../vnode/VNodeUtils'; import { markVNodePath } from '../utils/vNodePath'; @@ -120,10 +114,12 @@ function getNodeType(newChild: any): string | null { function setVNodeAdditionFlag(newNode: VNode, lastPosition: number): number { let position = lastPosition; - if (newNode.isCreated || newNode.eIndex < lastPosition) { // 位置 小于 上一个复用的位置 + if (newNode.isCreated || newNode.eIndex < lastPosition) { + // 位置 小于 上一个复用的位置 // 标记为新增 FlagUtils.setAddition(newNode); - } else { // 复用 + } else { + // 复用 position = newNode.eIndex; } @@ -206,15 +202,16 @@ function transRightChildrenToArray(child) { return rightChildrenArray; } -function transLeftChildrenToMap( - startChild: VNode, - rightEndVNode: VNode | null, -): Map { +function transLeftChildrenToMap(startChild: VNode, rightEndVNode: VNode | null): Map { const leftChildrenMap: Map = new Map(); - travelChildren(startChild, node => { - leftChildrenMap.set(node.key !== null ? node.key : node.eIndex, node); - }, node => node === rightEndVNode); + travelChildren( + startChild, + node => { + leftChildrenMap.set(node.key !== null ? node.key : node.eIndex, node); + }, + node => node === rightEndVNode + ); return leftChildrenMap; } @@ -235,11 +232,7 @@ function getOldNodeFromMap(nodeMap: Map, newIdx: number, } // diff数组类型的节点,核心算法 -function diffArrayNodesHandler( - parentNode: VNode, - firstChild: VNode | null, - newChildren: Array, -): VNode | null { +function diffArrayNodesHandler(parentNode: VNode, firstChild: VNode | null, newChildren: Array): VNode | null { let resultingFirstChild: VNode | null = null; let prevNewNode: VNode | null = null; @@ -358,7 +351,7 @@ function diffArrayNodesHandler( if (rightNewNode) { appendNode(rightNewNode); - setVNodesCIndex(rightNewNode, prevNewNode.cIndex + 1); + setVNodesCIndex(rightNewNode, rightNewNode.cIndex + 1); } return resultingFirstChild; @@ -366,13 +359,14 @@ function diffArrayNodesHandler( // 4. 新节点还有一部分,但是老节点已经没有了 if (oldNode === null) { - let isDirectAdd = false; // TODO: 是否可以扩大至非dom类型节点 // 如果dom节点在上次添加前没有节点,说明本次添加时,可以直接添加到最后,不需要通过 getSiblingDom 函数找到 before 节点 - if (parentNode.tag === DomComponent && + if ( + parentNode.tag === DomComponent && parentNode.oldProps?.children?.length === 0 && - rightIdx - leftIdx === newChildren.length) { + rightIdx - leftIdx === newChildren.length + ) { isDirectAdd = true; } const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated; @@ -424,7 +418,8 @@ function diffArrayNodesHandler( const eIndex = newNode.eIndex; eIndexes.push(eIndex); last = eIndexes[result[result.length - 1]]; - if (eIndex > last || last === undefined) { // 大的 eIndex直接放在最后 + if (eIndex > last || last === undefined) { + // 大的 eIndex直接放在最后 preIndex[i] = result[result.length - 1]; result.push(i); } else { @@ -500,13 +495,13 @@ function setVNodesCIndex(startChild: VNode | null, startIdx: number) { function diffIteratorNodesHandler( parentNode: VNode, firstChild: VNode | null, - newChildrenIterable: Iterable, + newChildrenIterable: Iterable ): VNode | null { const iteratorFn = getIteratorFn(newChildrenIterable); - const iteratorObj = iteratorFn.call(newChildrenIterable); + const iteratorObj: Iterator = iteratorFn.call(newChildrenIterable); // 把iterator转测数组 - const childrenArray = []; + const childrenArray: any[] = []; let result = iteratorObj.next(); while (!result.done) { childrenArray.push(result.value); @@ -517,12 +512,7 @@ function diffIteratorNodesHandler( } // 新节点是字符串类型 -function diffStringNodeHandler( - parentNode: VNode, - newChild: any, - firstChildVNode: VNode, - isComparing: boolean -) { +function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode: VNode | null, isComparing: boolean) { let newTextNode: VNode | null = null; // 第一个vNode是Text,则复用 @@ -550,7 +540,6 @@ function diffObjectNodeHandler( parentNode: VNode, firstChild: VNode | null, newChild: any, - firstChildVNode: VNode, isComparing: boolean ) { let canReuseNode: VNode | null = null; @@ -569,7 +558,7 @@ function diffObjectNodeHandler( } let resultNode: VNode | null = null; - let startDelVNode = firstChildVNode; + let startDelVNode: VNode | null = firstChild; if (newChild.vtype === TYPE_COMMON_ELEMENT) { if (canReuseNode) { // 可以复用 @@ -664,7 +653,7 @@ export function createChildrenByDiff( // 5. newChild是对象类型 if (isObjectType(newChild)) { - const newVNodes = diffObjectNodeHandler(parentNode, firstChild, newChild, firstChild, isComparing); + const newVNodes = diffObjectNodeHandler(parentNode, firstChild, newChild, isComparing); if (newVNodes) { return newVNodes; }