[Perf] Teact: Some minor optimizations
This commit is contained in:
parent
51b2893b39
commit
1f1c30fd0f
@ -76,18 +76,20 @@ function renderWithVirtual(
|
|||||||
moveDirection?: 'up' | 'down';
|
moveDirection?: 'up' | 'down';
|
||||||
} = {},
|
} = {},
|
||||||
) {
|
) {
|
||||||
|
const isCurrentComponent = $current && isComponentElement($current);
|
||||||
|
const isNewComponent = $new && isComponentElement($new);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!skipComponentUpdate
|
!skipComponentUpdate
|
||||||
&& $current && $new
|
&& isCurrentComponent && isNewComponent
|
||||||
&& isComponentElement($current) && isComponentElement($new)
|
&& !hasElementChanged($current!, $new!)
|
||||||
&& !hasElementChanged($current, $new)
|
|
||||||
) {
|
) {
|
||||||
$new = updateComponent($current, $new);
|
$new = updateComponent($current as VirtualElementComponent, $new as VirtualElementComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parent element may have changed, so we need to update the listener closure.
|
// Parent element may have changed, so we need to update the listener closure.
|
||||||
if (!skipComponentUpdate && $new && isComponentElement($new) && $new.componentInstance.isMounted) {
|
if (!skipComponentUpdate && isNewComponent && ($new as VirtualElementComponent).componentInstance.isMounted) {
|
||||||
setupComponentUpdateListener($new, $parent, index, parentEl);
|
setupComponentUpdateListener($new as VirtualElementComponent, $parent, index, parentEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($current === $new) {
|
if ($current === $new) {
|
||||||
@ -95,8 +97,8 @@ function renderWithVirtual(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$current && $new) {
|
if (!$current && $new) {
|
||||||
if (isComponentElement($new)) {
|
if (isNewComponent) {
|
||||||
$new = initComponent($new, $parent, index, parentEl);
|
$new = initComponent($new as VirtualElementComponent, $parent, index, parentEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = createNode($new);
|
const node = createNode($new);
|
||||||
@ -112,8 +114,8 @@ function renderWithVirtual(
|
|||||||
unmountTree($current);
|
unmountTree($current);
|
||||||
} else if ($current && $new) {
|
} else if ($current && $new) {
|
||||||
if (hasElementChanged($current, $new)) {
|
if (hasElementChanged($current, $new)) {
|
||||||
if (isComponentElement($new)) {
|
if (isNewComponent) {
|
||||||
$new = initComponent($new, $parent, index, parentEl);
|
$new = initComponent($new as VirtualElementComponent, $parent, index, parentEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = createNode($new);
|
const node = createNode($new);
|
||||||
@ -121,7 +123,7 @@ function renderWithVirtual(
|
|||||||
parentEl.replaceChild(node, getTarget($current)!);
|
parentEl.replaceChild(node, getTarget($current)!);
|
||||||
unmountTree($current);
|
unmountTree($current);
|
||||||
} else {
|
} else {
|
||||||
const areComponents = isComponentElement($current) && isComponentElement($new);
|
const areComponents = isCurrentComponent && isNewComponent;
|
||||||
const currentTarget = getTarget($current);
|
const currentTarget = getTarget($current);
|
||||||
|
|
||||||
if (!areComponents) {
|
if (!areComponents) {
|
||||||
@ -133,7 +135,7 @@ function renderWithVirtual(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRealElement($current) && isRealElement($new)) {
|
if (isRealElement($new)) {
|
||||||
if (moveDirection) {
|
if (moveDirection) {
|
||||||
const node = currentTarget!;
|
const node = currentTarget!;
|
||||||
const nextSibling = parentEl.childNodes[moveDirection === 'up' ? index : index + 1];
|
const nextSibling = parentEl.childNodes[moveDirection === 'up' ? index : index + 1];
|
||||||
@ -146,11 +148,11 @@ function renderWithVirtual(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!areComponents) {
|
if (!areComponents) {
|
||||||
updateAttributes($current, $new, currentTarget as HTMLElement);
|
updateAttributes(($current as VirtualRealElement), $new, currentTarget as HTMLElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
$new.children = renderChildren(
|
$new.children = renderChildren(
|
||||||
$current,
|
($current as VirtualRealElement),
|
||||||
$new,
|
$new,
|
||||||
areComponents ? parentEl : currentTarget as HTMLElement,
|
areComponents ? parentEl : currentTarget as HTMLElement,
|
||||||
);
|
);
|
||||||
@ -228,9 +230,9 @@ function createNode($element: VirtualElement): Node {
|
|||||||
props.ref.current = element;
|
props.ref.current = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(props).forEach((key) => {
|
Object.entries(props).forEach(([key, value]) => {
|
||||||
if (props[key] !== undefined) {
|
if (props[key] !== undefined) {
|
||||||
setAttribute(element, key, props[key]);
|
setAttribute(element, key, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -248,9 +250,11 @@ function renderChildren(
|
|||||||
return renderFastListChildren($current, $new, currentEl);
|
return renderFastListChildren($current, $new, currentEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxLength = Math.max($current.children.length, $new.children.length);
|
const currentChildrenLength = $current.children.length;
|
||||||
|
const newChildrenLength = $new.children.length;
|
||||||
|
const maxLength = Math.max(currentChildrenLength, newChildrenLength);
|
||||||
const newChildren = [];
|
const newChildren = [];
|
||||||
const fragment = $new.children.length > $current.children.length + 1 ? document.createDocumentFragment() : undefined;
|
const fragment = newChildrenLength > currentChildrenLength + 1 ? document.createDocumentFragment() : undefined;
|
||||||
|
|
||||||
for (let i = 0; i < maxLength; i++) {
|
for (let i = 0; i < maxLength; i++) {
|
||||||
const $newChild = renderWithVirtual(
|
const $newChild = renderWithVirtual(
|
||||||
@ -259,7 +263,7 @@ function renderChildren(
|
|||||||
$new.children[i],
|
$new.children[i],
|
||||||
$new,
|
$new,
|
||||||
i,
|
i,
|
||||||
i >= $current.children.length ? { fragment } : undefined,
|
i >= currentChildrenLength ? { fragment } : undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($newChild) {
|
if ($newChild) {
|
||||||
@ -364,9 +368,7 @@ function renderFastListChildren($current: VirtualRealElement, $new: VirtualRealE
|
|||||||
newChildren.push(
|
newChildren.push(
|
||||||
renderWithVirtual(currentEl, currentChildInfo.$element, $newChild, $new, i, {
|
renderWithVirtual(currentEl, currentChildInfo.$element, $newChild, $new, i, {
|
||||||
forceIndex: true,
|
forceIndex: true,
|
||||||
...(shouldMoveNode && {
|
moveDirection: shouldMoveNode ? (isMovingDown ? 'down' : 'up') : undefined,
|
||||||
moveDirection: isMovingDown ? 'down' : 'up',
|
|
||||||
}),
|
|
||||||
})!,
|
})!,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -402,11 +404,10 @@ function flushFragmentQueue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateAttributes($current: VirtualRealElement, $new: VirtualRealElement, element: HTMLElement) {
|
function updateAttributes($current: VirtualRealElement, $new: VirtualRealElement, element: HTMLElement) {
|
||||||
const currentKeys = Object.keys($current.props);
|
const currentEntries = Object.entries($current.props);
|
||||||
const newKeys = Object.keys($new.props);
|
const newEntries = Object.entries($new.props);
|
||||||
|
|
||||||
currentKeys.forEach((key) => {
|
currentEntries.forEach(([key, currentValue]) => {
|
||||||
const currentValue = $current.props[key];
|
|
||||||
const newValue = $new.props[key];
|
const newValue = $new.props[key];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -420,9 +421,8 @@ function updateAttributes($current: VirtualRealElement, $new: VirtualRealElement
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
newKeys.forEach((key) => {
|
newEntries.forEach(([key, newValue]) => {
|
||||||
const currentValue = $current.props[key];
|
const currentValue = $current.props[key];
|
||||||
const newValue = $new.props[key];
|
|
||||||
|
|
||||||
if (newValue !== undefined && newValue !== currentValue) {
|
if (newValue !== undefined && newValue !== currentValue) {
|
||||||
setAttribute(element, key, newValue);
|
setAttribute(element, key, newValue);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user