Optimize findViewByNodeId with an O(1) view map (m.__router_viewMap)
Problem
findViewByNodeId previously iterated over all children of viewTarget and keepAliveViewTarget to find a view by node ID. This is O(n) in the stack depth and is called on every goBack and popToCheckpoint.
Proposal
Introduce m.__router_viewMap — an associative array keyed by node ID that tracks every live view and whether it currently lives in viewTarget or keepAliveViewTarget.
findViewByNodeId now does a single AA lookup instead of looping over node children.
Map maintenance
The map is kept in sync at every point where a view changes ID, location, or lifetime:
| Event |
Action |
View added to viewTarget in addViewToStack |
viewMap[id] = { ..., fromKeepAlive: false } |
View suspended to keepAliveViewTarget (forward nav or suspendView) |
viewMap[id] = { ..., fromKeepAlive: true } |
keepAlive view ID reassigned on reuse in addViewToStack |
viewMap.delete(old id) before reassign |
View reparented back to viewTarget (_goBack, _popToCheckpoint) |
viewMap[id] = { ..., fromKeepAlive: false } |
View destroyed in closeView |
viewMap.delete(id) |
View destroyed inline in addViewToStack (non-keepAlive close loop) |
viewMap.delete(id) |
Router destroyed in _destroy |
m.__router_viewMap = {} |
Impact
findViewByNodeId is now O(1) regardless of stack depth.
- No change to observable behaviour — the map mirrors the existing node-tree structure exactly.
Optimize
findViewByNodeIdwith an O(1) view map (m.__router_viewMap)Problem
findViewByNodeIdpreviously iterated over all children ofviewTargetandkeepAliveViewTargetto find a view by node ID. This is O(n) in the stack depth and is called on everygoBackandpopToCheckpoint.Proposal
Introduce
m.__router_viewMap— an associative array keyed by node ID that tracks every live view and whether it currently lives inviewTargetorkeepAliveViewTarget.findViewByNodeIdnow does a single AA lookup instead of looping over node children.Map maintenance
The map is kept in sync at every point where a view changes ID, location, or lifetime:
viewTargetinaddViewToStackviewMap[id] = { ..., fromKeepAlive: false }keepAliveViewTarget(forward nav orsuspendView)viewMap[id] = { ..., fromKeepAlive: true }keepAliveview ID reassigned on reuse inaddViewToStackviewMap.delete(old id)before reassignviewTarget(_goBack,_popToCheckpoint)viewMap[id] = { ..., fromKeepAlive: false }closeViewviewMap.delete(id)addViewToStack(non-keepAlive close loop)viewMap.delete(id)_destroym.__router_viewMap = {}Impact
findViewByNodeIdis now O(1) regardless of stack depth.