@samitouri / QOS-React-1 / commits / 58ac15cdc9

devtools: emit performance entries only when profiling (#33652)

## Summary This floods Timings track in dev mode and also hurts performance in dev. Making sure we are buffering Performance entries (all of them are marks) only when profiling in RDT. This should be removed once we roll out Perf tracks.

Ruslan Lesiutin committed Jun 27, 2025 at 15:32 UTC 58ac15cdc953a21ac1b352b6300abc3da87fa3d6
1 file changed +119 -147
packages/react-devtools-shared/src/backend/profilingHooks.js
+119 -147
@@ -329,21 +329,17 @@ export function createProfilingHooks({
329 }
330
331 function markComponentRenderStarted(fiber: Fiber): void {
332 - if (isProfiling || supportsUserTimingV3) {
332 + if (isProfiling) {
333 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
334
335 - if (isProfiling) {
336 - // TODO (timeline) Record and cache component stack
337 - if (isProfiling) {
338 - currentReactComponentMeasure = {
339 - componentName,
340 - duration: 0,
341 - timestamp: getRelativeTime(),
342 - type: 'render',
343 - warning: null,
344 - };
345 - }
346 - }
335 + // TODO (timeline) Record and cache component stack
336 + currentReactComponentMeasure = {
337 + componentName,
338 + duration: 0,
339 + timestamp: getRelativeTime(),
340 + type: 'render',
341 + warning: null,
342 + };
343
344 if (supportsUserTimingV3) {
345 markAndClear(`--component-render-start-${componentName}`);
@@ -374,21 +370,17 @@ export function createProfilingHooks({
370 }
371
372 function markComponentLayoutEffectMountStarted(fiber: Fiber): void {
377 - if (isProfiling || supportsUserTimingV3) {
373 + if (isProfiling) {
374 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
375
380 - if (isProfiling) {
381 - // TODO (timeline) Record and cache component stack
382 - if (isProfiling) {
383 - currentReactComponentMeasure = {
384 - componentName,
385 - duration: 0,
386 - timestamp: getRelativeTime(),
387 - type: 'layout-effect-mount',
388 - warning: null,
389 - };
390 - }
391 - }
376 + // TODO (timeline) Record and cache component stack
377 + currentReactComponentMeasure = {
378 + componentName,
379 + duration: 0,
380 + timestamp: getRelativeTime(),
381 + type: 'layout-effect-mount',
382 + warning: null,
383 + };
384
385 if (supportsUserTimingV3) {
386 markAndClear(`--component-layout-effect-mount-start-${componentName}`);
@@ -419,21 +411,17 @@ export function createProfilingHooks({
411 }
412
413 function markComponentLayoutEffectUnmountStarted(fiber: Fiber): void {
422 - if (isProfiling || supportsUserTimingV3) {
414 + if (isProfiling) {
415 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
416
425 - if (isProfiling) {
426 - // TODO (timeline) Record and cache component stack
427 - if (isProfiling) {
428 - currentReactComponentMeasure = {
429 - componentName,
430 - duration: 0,
431 - timestamp: getRelativeTime(),
432 - type: 'layout-effect-unmount',
433 - warning: null,
434 - };
435 - }
436 - }
417 + // TODO (timeline) Record and cache component stack
418 + currentReactComponentMeasure = {
419 + componentName,
420 + duration: 0,
421 + timestamp: getRelativeTime(),
422 + type: 'layout-effect-unmount',
423 + warning: null,
424 + };
425
426 if (supportsUserTimingV3) {
427 markAndClear(
@@ -466,21 +454,17 @@ export function createProfilingHooks({
454 }
455
456 function markComponentPassiveEffectMountStarted(fiber: Fiber): void {
469 - if (isProfiling || supportsUserTimingV3) {
457 + if (isProfiling) {
458 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
459
472 - if (isProfiling) {
473 - // TODO (timeline) Record and cache component stack
474 - if (isProfiling) {
475 - currentReactComponentMeasure = {
476 - componentName,
477 - duration: 0,
478 - timestamp: getRelativeTime(),
479 - type: 'passive-effect-mount',
480 - warning: null,
481 - };
482 - }
483 - }
460 + // TODO (timeline) Record and cache component stack
461 + currentReactComponentMeasure = {
462 + componentName,
463 + duration: 0,
464 + timestamp: getRelativeTime(),
465 + type: 'passive-effect-mount',
466 + warning: null,
467 + };
468
469 if (supportsUserTimingV3) {
470 markAndClear(`--component-passive-effect-mount-start-${componentName}`);
@@ -511,21 +495,17 @@ export function createProfilingHooks({
495 }
496
497 function markComponentPassiveEffectUnmountStarted(fiber: Fiber): void {
514 - if (isProfiling || supportsUserTimingV3) {
498 + if (isProfiling) {
499 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
500
517 - if (isProfiling) {
518 - // TODO (timeline) Record and cache component stack
519 - if (isProfiling) {
520 - currentReactComponentMeasure = {
521 - componentName,
522 - duration: 0,
523 - timestamp: getRelativeTime(),
524 - type: 'passive-effect-unmount',
525 - warning: null,
526 - };
527 - }
528 - }
501 + // TODO (timeline) Record and cache component stack
502 + currentReactComponentMeasure = {
503 + componentName,
504 + duration: 0,
505 + timestamp: getRelativeTime(),
506 + type: 'passive-effect-unmount',
507 + warning: null,
508 + };
509
510 if (supportsUserTimingV3) {
511 markAndClear(
@@ -562,7 +542,7 @@ export function createProfilingHooks({
542 thrownValue: mixed,
543 lanes: Lanes,
544 ): void {
565 - if (isProfiling || supportsUserTimingV3) {
545 + if (isProfiling) {
546 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
547 const phase = fiber.alternate === null ? 'mount' : 'update';
548
@@ -577,17 +557,15 @@ export function createProfilingHooks({
557 message = thrownValue;
558 }
559
580 - if (isProfiling) {
581 - // TODO (timeline) Record and cache component stack
582 - if (currentTimelineData) {
583 - currentTimelineData.thrownErrors.push({
584 - componentName,
585 - message,
586 - phase,
587 - timestamp: getRelativeTime(),
588 - type: 'thrown-error',
589 - });
590 - }
560 + // TODO (timeline) Record and cache component stack
561 + if (currentTimelineData) {
562 + currentTimelineData.thrownErrors.push({
563 + componentName,
564 + message,
565 + phase,
566 + timestamp: getRelativeTime(),
567 + type: 'thrown-error',
568 + });
569 }
570
571 if (supportsUserTimingV3) {
@@ -613,7 +591,7 @@ export function createProfilingHooks({
591 wakeable: Wakeable,
592 lanes: Lanes,
593 ): void {
616 - if (isProfiling || supportsUserTimingV3) {
594 + if (isProfiling) {
595 const eventType = wakeableIDs.has(wakeable) ? 'resuspend' : 'suspend';
596 const id = getWakeableID(wakeable);
597 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
@@ -626,56 +604,54 @@ export function createProfilingHooks({
604 const displayName = (wakeable: any).displayName || '';
605
606 let suspenseEvent: SuspenseEvent | null = null;
629 - if (isProfiling) {
630 - // TODO (timeline) Record and cache component stack
631 - suspenseEvent = {
632 - componentName,
633 - depth: 0,
634 - duration: 0,
635 - id: `${id}`,
636 - phase,
637 - promiseName: displayName,
638 - resolution: 'unresolved',
639 - timestamp: getRelativeTime(),
640 - type: 'suspense',
641 - warning: null,
642 - };
607 + // TODO (timeline) Record and cache component stack
608 + suspenseEvent = {
609 + componentName,
610 + depth: 0,
611 + duration: 0,
612 + id: `${id}`,
613 + phase,
614 + promiseName: displayName,
615 + resolution: 'unresolved',
616 + timestamp: getRelativeTime(),
617 + type: 'suspense',
618 + warning: null,
619 + };
620
644 - if (currentTimelineData) {
645 - currentTimelineData.suspenseEvents.push(suspenseEvent);
646 - }
621 + if (currentTimelineData) {
622 + currentTimelineData.suspenseEvents.push(suspenseEvent);
623 }
624
625 if (supportsUserTimingV3) {
626 markAndClear(
627 `--suspense-${eventType}-${id}-${componentName}-${phase}-${lanes}-${displayName}`,
628 );
653 - }
629
655 - wakeable.then(
656 - () => {
657 - if (suspenseEvent) {
658 - suspenseEvent.duration =
659 - getRelativeTime() - suspenseEvent.timestamp;
660 - suspenseEvent.resolution = 'resolved';
661 - }
630 + wakeable.then(
631 + () => {
632 + if (suspenseEvent) {
633 + suspenseEvent.duration =
634 + getRelativeTime() - suspenseEvent.timestamp;
635 + suspenseEvent.resolution = 'resolved';
636 + }
637
663 - if (supportsUserTimingV3) {
664 - markAndClear(`--suspense-resolved-${id}-${componentName}`);
665 - }
666 - },
667 - () => {
668 - if (suspenseEvent) {
669 - suspenseEvent.duration =
670 - getRelativeTime() - suspenseEvent.timestamp;
671 - suspenseEvent.resolution = 'rejected';
672 - }
638 + if (supportsUserTimingV3) {
639 + markAndClear(`--suspense-resolved-${id}-${componentName}`);
640 + }
641 + },
642 + () => {
643 + if (suspenseEvent) {
644 + suspenseEvent.duration =
645 + getRelativeTime() - suspenseEvent.timestamp;
646 + suspenseEvent.resolution = 'rejected';
647 + }
648
674 - if (supportsUserTimingV3) {
675 - markAndClear(`--suspense-rejected-${id}-${componentName}`);
676 - }
677 - },
678 - );
649 + if (supportsUserTimingV3) {
650 + markAndClear(`--suspense-rejected-${id}-${componentName}`);
651 + }
652 + },
653 + );
654 + }
655 }
656 }
657
@@ -782,20 +758,18 @@ export function createProfilingHooks({
758 }
759
760 function markForceUpdateScheduled(fiber: Fiber, lane: Lane): void {
785 - if (isProfiling || supportsUserTimingV3) {
761 + if (isProfiling) {
762 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
763
788 - if (isProfiling) {
789 - // TODO (timeline) Record and cache component stack
790 - if (currentTimelineData) {
791 - currentTimelineData.schedulingEvents.push({
792 - componentName,
793 - lanes: laneToLanesArray(lane),
794 - timestamp: getRelativeTime(),
795 - type: 'schedule-force-update',
796 - warning: null,
797 - });
798 - }
764 + // TODO (timeline) Record and cache component stack
765 + if (currentTimelineData) {
766 + currentTimelineData.schedulingEvents.push({
767 + componentName,
768 + lanes: laneToLanesArray(lane),
769 + timestamp: getRelativeTime(),
770 + type: 'schedule-force-update',
771 + warning: null,
772 + });
773 }
774
775 if (supportsUserTimingV3) {
@@ -815,25 +789,23 @@ export function createProfilingHooks({
789 }
790
791 function markStateUpdateScheduled(fiber: Fiber, lane: Lane): void {
818 - if (isProfiling || supportsUserTimingV3) {
792 + if (isProfiling) {
793 const componentName = getDisplayNameForFiber(fiber) || 'Unknown';
794
821 - if (isProfiling) {
822 - // TODO (timeline) Record and cache component stack
823 - if (currentTimelineData) {
824 - const event: ReactScheduleStateUpdateEvent = {
825 - componentName,
826 - // Store the parent fibers so we can post process
827 - // them after we finish profiling
828 - lanes: laneToLanesArray(lane),
829 - timestamp: getRelativeTime(),
830 - type: 'schedule-state-update',
831 - warning: null,
832 - };
833 - currentFiberStacks.set(event, getParentFibers(fiber));
834 - // $FlowFixMe[incompatible-use] found when upgrading Flow
835 - currentTimelineData.schedulingEvents.push(event);
836 - }
795 + // TODO (timeline) Record and cache component stack
796 + if (currentTimelineData) {
797 + const event: ReactScheduleStateUpdateEvent = {
798 + componentName,
799 + // Store the parent fibers so we can post process
800 + // them after we finish profiling
801 + lanes: laneToLanesArray(lane),
802 + timestamp: getRelativeTime(),
803 + type: 'schedule-state-update',
804 + warning: null,
805 + };
806 + currentFiberStacks.set(event, getParentFibers(fiber));
807 + // $FlowFixMe[incompatible-use] found when upgrading Flow
808 + currentTimelineData.schedulingEvents.push(event);
809 }
810
811 if (supportsUserTimingV3) {