@samitouri / QOS-React-2 / commits / 6cfc9c1ff3

[DevTools] Don't measure fallbacks when suspended (#34850)

We already do this in the update pass. That's what `shouldMeasureSuspenseNode` does. We also don't update measurements when we're inside an offscreen tree. However, we didn't check if the boundary itself was in a suspended state when in the `measureUnchangedSuspenseNodesRecursively` path. This caused boundaries to disappear when their fallback didn't have a rect (including their timeline entries).

Sebastian Markbåge committed Oct 15, 2025 at 10:12 UTC 6cfc9c1ff3138ba0d107b9e6249f47032c4da02d
1 file changed +21 -6
packages/react-devtools-shared/src/backend/fiber/renderer.js
+21 -6
@@ -3262,14 +3262,22 @@ export function attach(
3262 // We don't update rects inside disconnected subtrees.
3263 return;
3264 }
3265 - const nextRects = measureInstance(suspenseNode.instance);
3266 - const prevRects = suspenseNode.rects;
3267 - if (areEqualRects(prevRects, nextRects)) {
3268 - return; // Unchanged
3265 + const instance = suspenseNode.instance;
3266 +
3267 + const isSuspendedSuspenseComponent =
3268 + (instance.kind === FIBER_INSTANCE ||
3269 + instance.kind === FILTERED_FIBER_INSTANCE) &&
3270 + instance.data.tag === SuspenseComponent &&
3271 + instance.data.memoizedState !== null;
3272 + if (isSuspendedSuspenseComponent) {
3273 + // This boundary itself was suspended and we don't measure those since that would measure
3274 + // the fallback. We want to keep a ghost of the rectangle of the content not currently shown.
3275 + return;
3276 }
3270 - // The rect has changed. While the bailed out root wasn't in a disconnected subtree,
3277 +
3278 + // While this boundary wasn't suspended and the bailed out root and wasn't in a disconnected subtree,
3279 // it's possible that this node was in one. So we need to check if we're offscreen.
3272 - let parent = suspenseNode.instance.parent;
3280 + let parent = instance.parent;
3281 while (parent !== null) {
3282 if (
3283 (parent.kind === FIBER_INSTANCE ||
@@ -3285,6 +3293,13 @@ export function attach(
3293 }
3294 parent = parent.parent;
3295 }
3296 +
3297 + const nextRects = measureInstance(suspenseNode.instance);
3298 + const prevRects = suspenseNode.rects;
3299 + if (areEqualRects(prevRects, nextRects)) {
3300 + return; // Unchanged
3301 + }
3302 +
3303 // We changed inside a visible tree.
3304 // Since this boundary changed, it's possible it also affected its children so lets
3305 // measure them as well.