Repository: facebook/react
File: packages/react-reconciler/src/ReactProfilerTimer.js (JavaScript)

Code before:
  }
  yieldStartTime = now();
  yieldReason = reason;
}

export function startUpdateTimerByLane(lane: Lane, method: string): void {
  if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
    return;
  }
  if (isSyncLane(lane) || isBlockingLane(lane)) {
    if (blockingUpdateTime < 0) {
      blockingUpdateTime = now();
      blockingUpdateTask = createTask(method);
      if (isAlreadyRendering()) {
        blockingUpdateType = SPAWNED_UPDATE;
      }
      const newEventTime = resolveEventTimeStamp();
      const newEventType = resolveEventType();
      if (
        newEventTime !== blockingEventTime ||
        newEventType !== blockingEventType
      ) {
        blockingEventIsRepeat = false;
      } else if (newEventType !== null) {
        // If this is a second update in the same event, we treat it as a spawned update.
        // This might be a microtask spawned from useEffect, multiple flushSync or
        // a setState in a microtask spawned after the first setState. Regardless it's bad.
        blockingUpdateType = SPAWNED_UPDATE;
      }
      blockingEventTime = newEventTime;
      blockingEventType = newEventType;
    }
  } else if (isTransitionLane(lane)) {
    if (transitionUpdateTime < 0) {
      transitionUpdateTime = now();
      transitionUpdateTask = createTask(method);
      if (transitionStartTime < 0) {
        const newEventTime = resolveEventTimeStamp();
        const newEventType = resolveEventType();
        if (
          newEventTime !== transitionEventTime ||
          newEventType !== transitionEventType
        ) {
          transitionEventIsRepeat = false;
        }
        transitionEventTime = newEventTime;
        transitionEventType = newEventType;
      }
    }
  }
}

Review comment (bug):
We should always set the component name even if it's null because otherwise we can show the wrong component name for the next call that is null.

Code after:
export let yieldStartTime: number = -1.1; // The time when we yielded to the event loop

export function startYieldTimer(reason: SuspendedReason) {
  if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
    return;
  }
  yieldStartTime = now();
  yieldReason = reason;
}

export function startUpdateTimerByLane(
  lane: Lane,
  method: string,
  fiber: Fiber | null,
): void {
  if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
    return;
  }
  if (isSyncLane(lane) || isBlockingLane(lane)) {
    if (blockingUpdateTime < 0) {
      blockingUpdateTime = now();
      blockingUpdateTask = createTask(method);
      blockingUpdateMethodName = method;
      if (__DEV__ && fiber != null) {
        blockingUpdateComponentName = getComponentNameFromFiber(fiber);
      }
      if (isAlreadyRendering()) {
        blockingUpdateType = SPAWNED_UPDATE;
      }
      const newEventTime = resolveEventTimeStamp();
      const newEventType = resolveEventType();
      if (
        newEventTime !== blockingEventTime ||
        newEventType !== blockingEventType
      ) {
        blockingEventIsRepeat = false;
      } else if (newEventType !== null) {
        // If this is a second update in the same event, we treat it as a spawned update.
        // This might be a microtask spawned from useEffect, multiple flushSync or
        // a setState in a microtask spawned after the first setState. Regardless it's bad.
        blockingUpdateType = SPAWNED_UPDATE;
      }
      blockingEventTime = newEventTime;
      blockingEventType = newEventType;
    }
  } else if (isTransitionLane(lane)) {
    if (transitionUpdateTime < 0) {
      transitionUpdateTime = now();
      transitionUpdateTask = createTask(method);
      transitionUpdateMethodName = method;
      if (__DEV__ && fiber != null) {