Skip to content

Commit 62960c6

Browse files
authored
Run Component Track Logs in the console.createTask() of the Fiber (facebook#32809)
Stacked on facebook#32736. That way you can find the owner stack of each component that rerendered for context. In addition to the JSX callsite tasks that we already track, I also added tracking of the first `setState` call before rendering. We then run the "Update" entries in that task. That way you can find the callsite of the first setState and therefore the "cause" of a render starting by selecting the "Update" track. Unfortunately this is blocked on bugs in Chrome that makes it so that these stacks are not reliable in the Performance tab. It basically just doesn't work.
1 parent cd4e4d7 commit 62960c6

File tree

7 files changed

+358
-113
lines changed

7 files changed

+358
-113
lines changed

packages/react-client/src/ReactFlightPerformanceTrack.js

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,30 @@ export function logComponentRender(
7878
: 'error';
7979
const entryName =
8080
isPrimaryEnv || env === undefined ? name : name + ' [' + env + ']';
81-
console.timeStamp(
82-
entryName,
83-
startTime < 0 ? 0 : startTime,
84-
childrenEndTime,
85-
trackNames[trackIdx],
86-
COMPONENTS_TRACK,
87-
color,
88-
);
81+
const debugTask = componentInfo.debugTask;
82+
if (__DEV__ && debugTask) {
83+
debugTask.run(
84+
// $FlowFixMe[method-unbinding]
85+
console.timeStamp.bind(
86+
console,
87+
entryName,
88+
startTime < 0 ? 0 : startTime,
89+
childrenEndTime,
90+
trackNames[trackIdx],
91+
COMPONENTS_TRACK,
92+
color,
93+
),
94+
);
95+
} else {
96+
console.timeStamp(
97+
entryName,
98+
startTime < 0 ? 0 : startTime,
99+
childrenEndTime,
100+
trackNames[trackIdx],
101+
COMPONENTS_TRACK,
102+
color,
103+
);
104+
}
89105
}
90106
}
91107

@@ -154,13 +170,29 @@ export function logDedupedComponentRender(
154170
if (supportsUserTiming && endTime >= 0 && trackIdx < 10) {
155171
const name = componentInfo.name;
156172
const entryName = name + ' [deduped]';
157-
console.timeStamp(
158-
entryName,
159-
startTime < 0 ? 0 : startTime,
160-
endTime,
161-
trackNames[trackIdx],
162-
COMPONENTS_TRACK,
163-
'tertiary-light',
164-
);
173+
const debugTask = componentInfo.debugTask;
174+
if (__DEV__ && debugTask) {
175+
debugTask.run(
176+
// $FlowFixMe[method-unbinding]
177+
console.timeStamp.bind(
178+
console,
179+
entryName,
180+
startTime < 0 ? 0 : startTime,
181+
endTime,
182+
trackNames[trackIdx],
183+
COMPONENTS_TRACK,
184+
'tertiary-light',
185+
),
186+
);
187+
} else {
188+
console.timeStamp(
189+
entryName,
190+
startTime < 0 ? 0 : startTime,
191+
endTime,
192+
trackNames[trackIdx],
193+
COMPONENTS_TRACK,
194+
'tertiary-light',
195+
);
196+
}
165197
}
166198
}

packages/react-reconciler/src/ReactFiberClassComponent.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ const classComponentUpdater = {
180180

181181
const root = enqueueUpdate(fiber, update, lane);
182182
if (root !== null) {
183-
startUpdateTimerByLane(lane);
183+
startUpdateTimerByLane(lane, 'this.setState()');
184184
scheduleUpdateOnFiber(root, fiber, lane);
185185
entangleTransitions(root, fiber, lane);
186186
}
@@ -206,7 +206,7 @@ const classComponentUpdater = {
206206

207207
const root = enqueueUpdate(fiber, update, lane);
208208
if (root !== null) {
209-
startUpdateTimerByLane(lane);
209+
startUpdateTimerByLane(lane, 'this.replaceState()');
210210
scheduleUpdateOnFiber(root, fiber, lane);
211211
entangleTransitions(root, fiber, lane);
212212
}
@@ -232,7 +232,7 @@ const classComponentUpdater = {
232232

233233
const root = enqueueUpdate(fiber, update, lane);
234234
if (root !== null) {
235-
startUpdateTimerByLane(lane);
235+
startUpdateTimerByLane(lane, 'this.forceUpdate()');
236236
scheduleUpdateOnFiber(root, fiber, lane);
237237
entangleTransitions(root, fiber, lane);
238238
}

packages/react-reconciler/src/ReactFiberHooks.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,8 @@ function updateStoreInstance<T>(
18471847
// snapsho and getSnapshot values to bail out. We need to check one more time.
18481848
if (checkIfSnapshotChanged(inst)) {
18491849
// Force a re-render.
1850+
// We intentionally don't log update times and stacks here because this
1851+
// was not an external trigger but rather an internal one.
18501852
forceStoreRerender(fiber);
18511853
}
18521854
}
@@ -1861,6 +1863,7 @@ function subscribeToStore<T>(
18611863
// read from the store.
18621864
if (checkIfSnapshotChanged(inst)) {
18631865
// Force a re-render.
1866+
startUpdateTimerByLane(SyncLane, 'updateSyncExternalStore()');
18641867
forceStoreRerender(fiber);
18651868
}
18661869
};
@@ -3503,7 +3506,7 @@ function refreshCache<T>(fiber: Fiber, seedKey: ?() => T, seedValue: T): void {
35033506
const refreshUpdate = createLegacyQueueUpdate(lane);
35043507
const root = enqueueLegacyQueueUpdate(provider, refreshUpdate, lane);
35053508
if (root !== null) {
3506-
startUpdateTimerByLane(lane);
3509+
startUpdateTimerByLane(lane, 'refresh()');
35073510
scheduleUpdateOnFiber(root, provider, lane);
35083511
entangleLegacyQueueTransitions(root, provider, lane);
35093512
}
@@ -3572,7 +3575,7 @@ function dispatchReducerAction<S, A>(
35723575
} else {
35733576
const root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
35743577
if (root !== null) {
3575-
startUpdateTimerByLane(lane);
3578+
startUpdateTimerByLane(lane, 'dispatch()');
35763579
scheduleUpdateOnFiber(root, fiber, lane);
35773580
entangleTransitionUpdate(root, queue, lane);
35783581
}
@@ -3606,7 +3609,7 @@ function dispatchSetState<S, A>(
36063609
lane,
36073610
);
36083611
if (didScheduleUpdate) {
3609-
startUpdateTimerByLane(lane);
3612+
startUpdateTimerByLane(lane, 'setState()');
36103613
}
36113614
markUpdateInDevTools(fiber, lane, action);
36123615
}
@@ -3768,7 +3771,7 @@ function dispatchOptimisticSetState<S, A>(
37683771
// will never be attempted before the optimistic update. This currently
37693772
// holds because the optimistic update is always synchronous. If we ever
37703773
// change that, we'll need to account for this.
3771-
startUpdateTimerByLane(lane);
3774+
startUpdateTimerByLane(lane, 'setOptimistic()');
37723775
scheduleUpdateOnFiber(root, fiber, lane);
37733776
// Optimistic updates are always synchronous, so we don't need to call
37743777
// entangleTransitionUpdate here.

0 commit comments

Comments
 (0)