Skip to content

Commit c6a043b

Browse files
committed
Refactor search traversals to avoid obj allocations
1 parent b57b847 commit c6a043b

File tree

1 file changed

+34
-21
lines changed

1 file changed

+34
-21
lines changed

packages/react-reconciler/src/ReactFiberTreeReflection.js

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -422,19 +422,30 @@ export function getInstanceFromHostFiber(fiber: Fiber): Instance {
422422
}
423423
}
424424

425+
let searchTarget = null;
426+
let searchBoundary = null;
427+
function pushSearchTarget(target: null | Fiber): void {
428+
searchTarget = target;
429+
}
430+
function popSearchTarget(): null | Fiber {
431+
return searchTarget;
432+
}
433+
function pushSearchBoundary(value: null | Fiber): void {
434+
searchBoundary = value;
435+
}
436+
function popSearchBoundary(): null | Fiber {
437+
return searchBoundary;
438+
}
439+
425440
export function getNextSiblingHostFiber(fiber: Fiber): null | Fiber {
426-
const searchState = {next: null};
427-
traverseVisibleHostChildren(
428-
fiber.sibling,
429-
false,
430-
findNextSibling,
431-
searchState,
432-
);
433-
return searchState.next;
441+
traverseVisibleHostChildren(fiber.sibling, false, findNextSibling);
442+
const sibling = popSearchTarget();
443+
pushSearchTarget(null);
444+
return sibling;
434445
}
435446

436-
function findNextSibling(child: Fiber, state: {next: null | Fiber}): boolean {
437-
state.next = child;
447+
function findNextSibling(child: Fiber): boolean {
448+
pushSearchTarget(child);
438449
return true;
439450
}
440451

@@ -467,29 +478,28 @@ export function isFiberPreceding(fiber: Fiber, otherFiber: Fiber): boolean {
467478
if (commonAncestor === null) {
468479
return false;
469480
}
470-
const searchState = {found: false};
471481
traverseVisibleHostChildren(
472482
commonAncestor,
473483
true,
474484
isFiberPrecedingCheck,
475485
otherFiber,
476486
fiber,
477-
searchState,
478487
);
479-
return searchState.found;
488+
const target = popSearchTarget();
489+
pushSearchTarget(null);
490+
return target !== null;
480491
}
481492

482493
function isFiberPrecedingCheck(
483494
child: Fiber,
484495
target: Fiber,
485496
boundary: Fiber,
486-
state: {found: boolean},
487497
): boolean {
488498
if (child === boundary) {
489499
return true;
490500
}
491501
if (child === target) {
492-
state.found = true;
502+
pushSearchTarget(child);
493503
return true;
494504
}
495505
return false;
@@ -504,30 +514,33 @@ export function isFiberFollowing(fiber: Fiber, otherFiber: Fiber): boolean {
504514
if (commonAncestor === null) {
505515
return false;
506516
}
507-
const searchState = {foundFiber: false, foundOther: false};
508517
traverseVisibleHostChildren(
509518
commonAncestor,
510519
true,
511520
isFiberFollowingCheck,
512521
otherFiber,
513522
fiber,
514-
searchState,
515523
);
516-
return searchState.foundOther;
524+
const target = popSearchTarget();
525+
pushSearchTarget(null);
526+
pushSearchBoundary(null);
527+
return target !== null;
517528
}
518529

519530
function isFiberFollowingCheck(
520531
child: Fiber,
521532
target: Fiber,
522533
boundary: Fiber,
523-
state: {foundFiber: boolean, foundOther: boolean},
524534
): boolean {
525535
if (child === boundary) {
526-
state.foundFiber = true;
536+
pushSearchBoundary(child);
527537
return false;
528538
}
529539
if (child === target) {
530-
state.foundOther = state.foundFiber;
540+
// The target is only following if we already found the boundary.
541+
if (popSearchBoundary() !== null) {
542+
pushSearchTarget(child);
543+
}
531544
return true;
532545
}
533546
return false;

0 commit comments

Comments
 (0)