From 81d8ed7d52a0a25ebeaa0888ddf35ba404af70b9 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Sun, 12 Oct 2025 20:27:42 -0400 Subject: [PATCH] Ignore suspense boundaries without visual representation in the timeline --- .../react-devtools-shared/src/devtools/store.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/react-devtools-shared/src/devtools/store.js b/packages/react-devtools-shared/src/devtools/store.js index 99971f6a1a697..eeb6da60f8aeb 100644 --- a/packages/react-devtools-shared/src/devtools/store.js +++ b/packages/react-devtools-shared/src/devtools/store.js @@ -51,6 +51,7 @@ import type { ComponentFilter, ElementType, SuspenseNode, + Rect, } from 'react-devtools-shared/src/frontend/types'; import type { FrontendBridge, @@ -99,6 +100,10 @@ export type Capabilities = { supportsAdvancedProfiling: AdvancedProfiling, }; +function isNonZeroRect(rect: Rect) { + return rect.width > 0 || rect.height > 0 || rect.x > 0 || rect.y > 0; +} + /** * The store is the single source of truth for updates from the backend. * ContextProviders can subscribe to the Store for specific things they want to provide. @@ -918,7 +923,15 @@ export default class Store extends EventEmitter<{ if (current === undefined) { continue; } + // Ignore any suspense boundaries that has no visual representation as this is not + // part of the visible loading sequence. + // TODO: Consider making visible meta data and other side-effects get virtual rects. + const hasRects = + current.rects !== null && + current.rects.length > 0 && + current.rects.some(isNonZeroRect); if ( + hasRects && (!uniqueSuspendersOnly || current.hasUniqueSuspenders) && // Roots are already included as part of the Screen current.id !== rootID