Repository: facebook/react
Pull request: [Flight] Color and badge non-primary environments

Stacked on #31737.

<img width="987" alt="Screenshot 2024-12-11 at 8 41 15 PM" src="https://github.com/user-attachments/assets/438379a9-0138-4d02-a53a-419402839558" />

When mixing environments (like "use cache" or third party RSC) it's useful to color and badge those components differently to differentiate.

I'm not putting them in separate tracks because when they do actually execute, like cache misses or third party RSCs, they behave like they're part of the same tree. 

Changed files:
filename: packages/react-client/src/ReactFlightClient.js
patch: @@ -649,7 +649,13 @@ export function reportGlobalError(response: Response, error: Error): void {
   });
   if (enableProfilerTimer && enableComponentPerformanceTrack) {
     markAllTracksInOrder();
-    flushComponentPerformance(getChunk(response, 0), 0, -Infinity, -Infinity);
+    flushComponentPerformance(
+      response,
+      getChunk(response, 0),
+      0,
+      -Infinity,
+      -Infinity,
+    );
   }
 }
 
@@ -2748,6 +2754,7 @@ function resolveTypedArray(
 }
 
 function flushComponentPerformance(
+  response: Response,
   root: SomeChunk<any>,
   trackIdx: number, // Next available track
   trackTime: number, // The time after which it is available,
@@ -2838,6 +2845,7 @@ function flushComponentPerformance(
   let childTrackTime = trackTime;
   for (let i = 0; i < children.length; i++) {
     const childResult = flushComponentPerformance(
+      response,
       children[i],
       childTrackIdx,
       childTrackTime,
@@ -2876,6 +2884,7 @@ function flushComponentPerformance(
             startTime,
             endTime,
             childrenEndTime,
+            response._rootEnvironmentName,
           );
           // Track the root most component of the result for deduping logging.
           result.component = componentInfo;

filename: packages/react-client/src/ReactFlightPerformanceTrack.js
patch: @@ -72,22 +72,33 @@ export function logComponentRender(
   startTime: number,
   endTime: number,
   childrenEndTime: number,
+  rootEnv: string,
 ): void {
   if (supportsUserTiming && childrenEndTime >= 0 && trackIdx < 10) {
+    const env = componentInfo.env;
     const name = componentInfo.name;
+    const isPrimaryEnv = env === rootEnv;
     const selfTime = endTime - startTime;
     reusableComponentDevToolDetails.color =
       selfTime < 0.5
-        ? 'primary-light'
+        ? isPrimaryEnv
+          ? 'primary-light'
+          : 'secondary-light'
         : selfTime < 50
-          ? 'primary'
+          ? isPrimaryEnv
+            ? 'primary'
+            : 'secondary'
           : selfTime < 500
-            ? 'primary-dark'
+            ? isPrimaryEnv
+              ? 'primary-dark'
+              : 'secondary-dark'
             : 'error';
     reusableComponentDevToolDetails.track = trackNames[trackIdx];
     reusableComponentOptions.start = startTime < 0 ? 0 : startTime;
     reusableComponentOptions.end = childrenEndTime;
-    performance.measure(name, reusableComponentOptions);
+    const entryName =
+      isPrimaryEnv || env === undefined ? name : name + ' [' + env + ']';
+    performance.measure(entryName, reusableComponentOptions);
   }
 }
 
@@ -103,6 +114,7 @@ export function logDedupedComponentRender(
     reusableComponentDevToolDetails.track = trackNames[trackIdx];
     reusableComponentOptions.start = startTime < 0 ? 0 : startTime;
     reusableComponentOptions.end = endTime;
-    performance.measure(name + ' [deduped]', reusableComponentOptions);
+    const entryName = name + ' [deduped]';
+    performance.measure(entryName, reusableComponentOptions);
   }
 }