提升性能,但这是一个整体的,积少成多的过程
ShapeFlags 使用二进制描述枚举类型、按位用算便于运算,优化性能
// 组件的类型
export const enum ShapeFlags {
// 最后要渲染的 element 二进制 0000 0001
ELEMENT = 1,
// 组件类型 二进制 0000 0100
STATEFUL_COMPONENT = 1 << 2,
// vnode 的 children 为 string 二进制 0000 1000
TEXT_CHILDREN = 1 << 3,
// vnode 的 children 为数组类型 二进制0001 0000
ARRAY_CHILDREN = 1 << 4,
// vnode 的 children 为 slots 类型 二进制 0010 0000
SLOTS_CHILDREN = 1 << 5
}
createVNode中 赋值, 使用 |= 赋值,“ | ”表示按位或, 为 vnode.shapeFlag
添加(ShapeFlags.ARRAY_CHILDREN |
ShapeFlags.TEXT_CHILDREN)值,以便于匹配的时候能够匹配到指定位置为1。
/
/ 默认类型
function getShapeFlag(type: any) {
return typeof type === "string"
? ShapeFlags.ELEMENT
: ShapeFlags.STATEFUL_COMPONENT;
}
// createVNode 中判断代码段
// 基于 children 再次设置 shapeFlag
if (Array.isArray(children)) {
// 基于默认类型,这里 shapeFlag 为 0000 0100
// ShapeFlags.ARRAY_CHILDREN = 0001 0000
// 结果 vnode.shapeFlag = 0001 0100 = 20
vnode.shapeFlag |= ShapeFlags.ARRAY_CHILDREN;
} else if (typeof children === "string") {
// 基于默认类型,这里 shapeFlag 为 0000 0000
// ShapeFlags.TEXT_CHILDREN = 0000 1000
// 结果 vnode.shapeFlag = 0000 1000 = 8
vnode.shapeFlag |= ShapeFlags.TEXT_CHILDREN;
}
createRenderer -> path 函数中调用,使用按位或 “&” 来判断是否指定位置是否能够满足条件
// 这里就基于 shapeFlag 来处理
// 判断是否满足第一位是1 ShapeFlags.ELEMENT = 0000 0001
if (shapeFlag & ShapeFlags.ELEMENT) {
console.log("处理 element");
processElement(n1, n2, container, anchor, parentComponent);
} else if (shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
// 判断是否满足第三位为1 ShapeFlags.ELEMENT = 0000 0100
console.log("处理 component");
processComponent(n1, n2, container, parentComponent);
}