Permanently removed component stacks from scheduling profiler data (#19615)
These stacks improve the profiler data but they're expensive to generate and generating them can also cause runtime errors in larger applications (although an exact repro has been hard to nail down). Removing them for now. We can revisit adding them after this profiler has been integrated into the DevTools extension and we can generate them lazily.
Brian Vaughn committed
Aug 14, 2020 at 15:21 UTC
9b35dd2fcc8b8dfbd1363cef9e5c59a0deab0dd3
12 files changed
+33
-172
packages/react-reconciler/src/SchedulingProfiler.js
+9
-52
@@ -11,13 +11,9 @@ import type {Lane, Lanes} from './ReactFiberLane';
11
import type {Fiber} from './ReactInternalTypes';
12
import type {Wakeable} from 'shared/ReactTypes';
13
14
-import {
15
- enableSchedulingProfiler,
16
- enableSchedulingProfilerComponentStacks,
17
-} from 'shared/ReactFeatureFlags';
14
+import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
15
import ReactVersion from 'shared/ReactVersion';
16
import getComponentName from 'shared/getComponentName';
20
-import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
17
18
/**
19
* If performance exists and supports the subset of the User Timing API that we
@@ -65,51 +61,16 @@ function getWakeableID(wakeable: Wakeable): number {
61
return ((wakeableIDs.get(wakeable): any): number);
62
}
63
68
-let getComponentStackByFiber = function getComponentStackByFiberDisabled(
69
- fiber: Fiber,
70
-): string {
71
- return '';
72
-};
73
-
74
-if (enableSchedulingProfilerComponentStacks) {
75
- // $FlowFixMe: Flow cannot handle polymorphic WeakMaps
76
- const cachedFiberStacks: WeakMap<Fiber, string> = new PossiblyWeakMap();
77
- getComponentStackByFiber = function cacheFirstGetComponentStackByFiber(
78
- fiber: Fiber,
79
- ): string {
80
- if (cachedFiberStacks.has(fiber)) {
81
- return ((cachedFiberStacks.get(fiber): any): string);
82
- } else {
83
- const alternate = fiber.alternate;
84
- if (alternate !== null && cachedFiberStacks.has(alternate)) {
85
- return ((cachedFiberStacks.get(alternate): any): string);
86
- }
87
- }
88
- // TODO (brian) Generate and store temporary ID so DevTools can match up a component stack later.
89
- const componentStack = getStackByFiberInDevAndProd(fiber) || '';
90
- cachedFiberStacks.set(fiber, componentStack);
91
- return componentStack;
92
- };
93
-}
94
-
64
export function markComponentSuspended(fiber: Fiber, wakeable: Wakeable): void {
65
if (enableSchedulingProfiler) {
66
if (supportsUserTiming) {
67
const id = getWakeableID(wakeable);
68
const componentName = getComponentName(fiber.type) || 'Unknown';
100
- const componentStack = getComponentStackByFiber(fiber);
101
- performance.mark(
102
- `--suspense-suspend-${id}-${componentName}-${componentStack}`,
103
- );
69
+ // TODO Add component stack id
70
+ performance.mark(`--suspense-suspend-${id}-${componentName}`);
71
wakeable.then(
105
- () =>
106
- performance.mark(
107
- `--suspense-resolved-${id}-${componentName}-${componentStack}`,
108
- ),
109
- () =>
110
- performance.mark(
111
- `--suspense-rejected-${id}-${componentName}-${componentStack}`,
112
- ),
72
+ () => performance.mark(`--suspense-resolved-${id}-${componentName}`),
73
+ () => performance.mark(`--suspense-rejected-${id}-${componentName}`),
74
);
75
}
76
}
@@ -183,11 +144,9 @@ export function markForceUpdateScheduled(fiber: Fiber, lane: Lane): void {
144
if (enableSchedulingProfiler) {
145
if (supportsUserTiming) {
146
const componentName = getComponentName(fiber.type) || 'Unknown';
186
- const componentStack = getComponentStackByFiber(fiber);
147
+ // TODO Add component stack id
148
performance.mark(
188
- `--schedule-forced-update-${formatLanes(
189
- lane,
190
- )}-${componentName}-${componentStack}`,
149
+ `--schedule-forced-update-${formatLanes(lane)}-${componentName}`,
150
);
151
}
152
}
@@ -197,11 +156,9 @@ export function markStateUpdateScheduled(fiber: Fiber, lane: Lane): void {
156
if (enableSchedulingProfiler) {
157
if (supportsUserTiming) {
158
const componentName = getComponentName(fiber.type) || 'Unknown';
200
- const componentStack = getComponentStackByFiber(fiber);
159
+ // TODO Add component stack id
160
performance.mark(
202
- `--schedule-state-update-${formatLanes(
203
- lane,
204
- )}-${componentName}-${componentStack}`,
161
+ `--schedule-state-update-${formatLanes(lane)}-${componentName}`,
162
);
163
}
164
}
packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js
+24
-105
@@ -12,29 +12,6 @@
12
13
import ReactVersion from 'shared/ReactVersion';
14
15
-function normalizeCodeLocInfo(str) {
16
- return (
17
- str &&
18
- str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function(m, name) {
19
- return '\n in ' + name + ' (at **)';
20
- })
21
- );
22
-}
23
-
24
-// TODO (enableSchedulingProfilerComponentStacks) Clean this up once the feature flag has been removed.
25
-function toggleComponentStacks(mark) {
26
- let expectedMark = mark;
27
- gate(({enableSchedulingProfilerComponentStacks}) => {
28
- if (!enableSchedulingProfilerComponentStacks) {
29
- const index = mark.indexOf('\n ');
30
- if (index >= 0) {
31
- expectedMark = mark.substr(0, index);
32
- }
33
- }
34
- });
35
- return expectedMark;
36
-}
37
-
15
describe('SchedulingProfiler', () => {
16
let React;
17
let ReactTestRenderer;
@@ -162,9 +139,7 @@ describe('SchedulingProfiler', () => {
139
`--react-init-${ReactVersion}`,
140
'--schedule-render-1',
141
'--render-start-1',
165
- toggleComponentStacks(
166
- '--suspense-suspend-0-Example-\n at Example\n at Suspense',
167
- ),
142
+ '--suspense-suspend-0-Example',
143
'--render-stop',
144
'--commit-start-1',
145
'--layout-effects-start-1',
@@ -175,11 +150,7 @@ describe('SchedulingProfiler', () => {
150
marks.splice(0);
151
152
await fakeSuspensePromise;
178
- expect(marks).toEqual([
179
- toggleComponentStacks(
180
- '--suspense-resolved-0-Example-\n at Example\n at Suspense',
181
- ),
182
- ]);
153
+ expect(marks).toEqual(['--suspense-resolved-0-Example']);
154
});
155
156
// @gate enableSchedulingProfiler
@@ -199,9 +170,7 @@ describe('SchedulingProfiler', () => {
170
`--react-init-${ReactVersion}`,
171
'--schedule-render-1',
172
'--render-start-1',
202
- toggleComponentStacks(
203
- '--suspense-suspend-0-Example-\n at Example\n at Suspense',
204
- ),
173
+ '--suspense-suspend-0-Example',
174
'--render-stop',
175
'--commit-start-1',
176
'--layout-effects-start-1',
@@ -212,11 +181,7 @@ describe('SchedulingProfiler', () => {
181
marks.splice(0);
182
183
await expect(fakeSuspensePromise).rejects.toThrow();
215
- expect(marks).toEqual([
216
- toggleComponentStacks(
217
- '--suspense-rejected-0-Example-\n at Example\n at Suspense',
218
- ),
219
- ]);
184
+ expect(marks).toEqual(['--suspense-rejected-0-Example']);
185
});
186
187
// @gate enableSchedulingProfiler
@@ -244,9 +209,7 @@ describe('SchedulingProfiler', () => {
209
210
expect(marks).toEqual([
211
'--render-start-512',
247
- toggleComponentStacks(
248
- '--suspense-suspend-0-Example-\n at Example\n at Suspense',
249
- ),
212
+ '--suspense-suspend-0-Example',
213
'--render-stop',
214
'--commit-start-512',
215
'--layout-effects-start-512',
@@ -257,11 +220,7 @@ describe('SchedulingProfiler', () => {
220
marks.splice(0);
221
222
await fakeSuspensePromise;
260
- expect(marks).toEqual([
261
- toggleComponentStacks(
262
- '--suspense-resolved-0-Example-\n at Example\n at Suspense',
263
- ),
264
- ]);
223
+ expect(marks).toEqual(['--suspense-resolved-0-Example']);
224
});
225
226
// @gate enableSchedulingProfiler
@@ -289,9 +248,7 @@ describe('SchedulingProfiler', () => {
248
249
expect(marks).toEqual([
250
'--render-start-512',
292
- toggleComponentStacks(
293
- '--suspense-suspend-0-Example-\n at Example\n at Suspense',
294
- ),
251
+ '--suspense-suspend-0-Example',
252
'--render-stop',
253
'--commit-start-512',
254
'--layout-effects-start-512',
@@ -302,11 +259,7 @@ describe('SchedulingProfiler', () => {
259
marks.splice(0);
260
261
await expect(fakeSuspensePromise).rejects.toThrow();
305
- expect(marks).toEqual([
306
- toggleComponentStacks(
307
- '--suspense-rejected-0-Example-\n at Example\n at Suspense',
308
- ),
309
- ]);
262
+ expect(marks).toEqual(['--suspense-rejected-0-Example']);
263
});
264
265
// @gate enableSchedulingProfiler
@@ -332,14 +285,12 @@ describe('SchedulingProfiler', () => {
285
286
expect(Scheduler).toFlushUntilNextPaint([]);
287
335
- expect(marks.map(normalizeCodeLocInfo)).toEqual([
288
+ expect(marks).toEqual([
289
'--render-start-512',
290
'--render-stop',
291
'--commit-start-512',
292
'--layout-effects-start-512',
340
- toggleComponentStacks(
341
- '--schedule-state-update-1-Example-\n in Example (at **)',
342
- ),
293
+ '--schedule-state-update-1-Example',
294
'--layout-effects-stop',
295
'--render-start-1',
296
'--render-stop',
@@ -371,14 +322,12 @@ describe('SchedulingProfiler', () => {
322
323
expect(Scheduler).toFlushUntilNextPaint([]);
324
374
- expect(marks.map(normalizeCodeLocInfo)).toEqual([
325
+ expect(marks).toEqual([
326
'--render-start-512',
327
'--render-stop',
328
'--commit-start-512',
329
'--layout-effects-start-512',
379
- toggleComponentStacks(
380
- '--schedule-forced-update-1-Example-\n in Example (at **)',
381
- ),
330
+ '--schedule-forced-update-1-Example',
331
'--layout-effects-stop',
332
'--render-start-1',
333
'--render-stop',
@@ -415,16 +364,8 @@ describe('SchedulingProfiler', () => {
364
365
gate(({old}) =>
366
old
418
- ? expect(marks.map(normalizeCodeLocInfo)).toContain(
419
- toggleComponentStacks(
420
- '--schedule-state-update-1024-Example-\n in Example (at **)',
421
- ),
422
- )
423
- : expect(marks.map(normalizeCodeLocInfo)).toContain(
424
- toggleComponentStacks(
425
- '--schedule-state-update-512-Example-\n in Example (at **)',
426
- ),
427
- ),
367
+ ? expect(marks).toContain('--schedule-state-update-1024-Example')
368
+ : expect(marks).toContain('--schedule-state-update-512-Example'),
369
);
370
});
371
@@ -455,16 +396,8 @@ describe('SchedulingProfiler', () => {
396
397
gate(({old}) =>
398
old
458
- ? expect(marks.map(normalizeCodeLocInfo)).toContain(
459
- toggleComponentStacks(
460
- '--schedule-forced-update-1024-Example-\n in Example (at **)',
461
- ),
462
- )
463
- : expect(marks.map(normalizeCodeLocInfo)).toContain(
464
- toggleComponentStacks(
465
- '--schedule-forced-update-512-Example-\n in Example (at **)',
466
- ),
467
- ),
399
+ ? expect(marks).toContain('--schedule-forced-update-1024-Example')
400
+ : expect(marks).toContain('--schedule-forced-update-512-Example'),
401
);
402
});
403
@@ -489,14 +422,12 @@ describe('SchedulingProfiler', () => {
422
423
expect(Scheduler).toFlushUntilNextPaint([]);
424
492
- expect(marks.map(normalizeCodeLocInfo)).toEqual([
425
+ expect(marks).toEqual([
426
'--render-start-512',
427
'--render-stop',
428
'--commit-start-512',
429
'--layout-effects-start-512',
497
- toggleComponentStacks(
498
- '--schedule-state-update-1-Example-\n in Example (at **)',
499
- ),
430
+ '--schedule-state-update-1-Example',
431
'--layout-effects-stop',
432
'--render-start-1',
433
'--render-stop',
@@ -522,7 +453,7 @@ describe('SchedulingProfiler', () => {
453
454
gate(({old}) => {
455
if (old) {
525
- expect(marks.map(normalizeCodeLocInfo)).toEqual([
456
+ expect(marks).toEqual([
457
`--react-init-${ReactVersion}`,
458
'--schedule-render-512',
459
'--render-start-512',
@@ -532,9 +463,7 @@ describe('SchedulingProfiler', () => {
463
'--layout-effects-stop',
464
'--commit-stop',
465
'--passive-effects-start-512',
535
- toggleComponentStacks(
536
- '--schedule-state-update-1024-Example-\n in Example (at **)',
537
- ),
466
+ '--schedule-state-update-1024-Example',
467
'--passive-effects-stop',
468
'--render-start-1024',
469
'--render-stop',
@@ -542,7 +471,7 @@ describe('SchedulingProfiler', () => {
471
'--commit-stop',
472
]);
473
} else {
545
- expect(marks.map(normalizeCodeLocInfo)).toEqual([
474
+ expect(marks).toEqual([
475
`--react-init-${ReactVersion}`,
476
'--schedule-render-512',
477
'--render-start-512',
@@ -552,9 +481,7 @@ describe('SchedulingProfiler', () => {
481
'--layout-effects-stop',
482
'--commit-stop',
483
'--passive-effects-start-512',
555
- toggleComponentStacks(
556
- '--schedule-state-update-1024-Example-\n in Example (at **)',
557
- ),
484
+ '--schedule-state-update-1024-Example',
485
'--passive-effects-stop',
486
'--render-start-1024',
487
'--render-stop',
@@ -583,16 +510,8 @@ describe('SchedulingProfiler', () => {
510
511
gate(({old}) =>
512
old
586
- ? expect(marks.map(normalizeCodeLocInfo)).toContain(
587
- toggleComponentStacks(
588
- '--schedule-state-update-1024-Example-\n in Example (at **)',
589
- ),
590
- )
591
- : expect(marks.map(normalizeCodeLocInfo)).toContain(
592
- toggleComponentStacks(
593
- '--schedule-state-update-512-Example-\n in Example (at **)',
594
- ),
595
- ),
513
+ ? expect(marks).toContain('--schedule-state-update-1024-Example')
514
+ : expect(marks).toContain('--schedule-state-update-512-Example'),
515
);
516
});
517
});
packages/shared/ReactFeatureFlags.js
-1
@@ -18,7 +18,6 @@ export const enableDebugTracing = false;
18
// Adds user timing marks for e.g. state updates, suspense, and work loop stuff,
19
// for an experimental scheduling profiler tool.
20
export const enableSchedulingProfiler = __PROFILE__ && __EXPERIMENTAL__;
21
-export const enableSchedulingProfilerComponentStacks = false;
21
22
// Helps identify side effects in render-phase lifecycle hooks and setState
23
// reducers by double invoking them in Strict Mode.
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -13,7 +13,6 @@ import typeof * as ExportsType from './ReactFeatureFlags.native-fb';
13
// The rest of the flags are static for better dead code elimination.
14
export const enableDebugTracing = false;
15
export const enableSchedulingProfiler = false;
16
-export const enableSchedulingProfilerComponentStacks = false;
16
export const enableProfilerTimer = __PROFILE__;
17
export const enableProfilerCommitHooks = false;
18
export const enableSchedulerTracing = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -13,7 +13,6 @@ import typeof * as ExportsType from './ReactFeatureFlags.native-oss';
13
export const debugRenderPhaseSideEffectsForStrictMode = false;
14
export const enableDebugTracing = false;
15
export const enableSchedulingProfiler = false;
16
-export const enableSchedulingProfilerComponentStacks = false;
16
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
17
export const warnAboutDeprecatedLifecycles = true;
18
export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -13,7 +13,6 @@ import typeof * as ExportsType from './ReactFeatureFlags.test-renderer';
13
export const debugRenderPhaseSideEffectsForStrictMode = false;
14
export const enableDebugTracing = false;
15
export const enableSchedulingProfiler = false;
16
-export const enableSchedulingProfilerComponentStacks = false;
16
export const warnAboutDeprecatedLifecycles = true;
17
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
18
export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
-1
@@ -13,7 +13,6 @@ import typeof * as ExportsType from './ReactFeatureFlags.test-renderer';
13
export const debugRenderPhaseSideEffectsForStrictMode = false;
14
export const enableDebugTracing = false;
15
export const enableSchedulingProfiler = false;
16
-export const enableSchedulingProfilerComponentStacks = false;
16
export const warnAboutDeprecatedLifecycles = true;
17
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
18
export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -13,7 +13,6 @@ import typeof * as ExportsType from './ReactFeatureFlags.test-renderer.www';
13
export const debugRenderPhaseSideEffectsForStrictMode = false;
14
export const enableDebugTracing = false;
15
export const enableSchedulingProfiler = false;
16
-export const enableSchedulingProfilerComponentStacks = false;
16
export const warnAboutDeprecatedLifecycles = true;
17
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
18
export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.testing.js
-1
@@ -13,7 +13,6 @@ import typeof * as ExportsType from './ReactFeatureFlags.testing';
13
export const debugRenderPhaseSideEffectsForStrictMode = false;
14
export const enableDebugTracing = false;
15
export const enableSchedulingProfiler = false;
16
-export const enableSchedulingProfilerComponentStacks = false;
16
export const warnAboutDeprecatedLifecycles = true;
17
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
18
export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.testing.www.js
-1
@@ -13,7 +13,6 @@ import typeof * as ExportsType from './ReactFeatureFlags.testing.www';
13
export const debugRenderPhaseSideEffectsForStrictMode = false;
14
export const enableDebugTracing = false;
15
export const enableSchedulingProfiler = false;
16
-export const enableSchedulingProfilerComponentStacks = false;
16
export const warnAboutDeprecatedLifecycles = true;
17
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
18
export const enableProfilerTimer = false;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-6
@@ -25,12 +25,6 @@ export const decoupleUpdatePriorityFromScheduler = __VARIANT__;
25
// NOTE: This feature will only work in DEV mode; all callsights are wrapped with __DEV__.
26
export const enableDebugTracing = false;
27
28
-// TODO: getStackByFiberInDevAndProd() causes errors when synced to www.
29
-// This flag can be used to disable component stacks for the profiler marks,
30
-// so that the feature can be synced for others,
31
-// while still enabling investigation into the underlying source of the errors.
32
-export const enableSchedulingProfilerComponentStacks = false;
33
-
28
// This only has an effect in the new reconciler. But also, the new reconciler
29
// is only enabled when __VARIANT__ is true. So this is set to the opposite of
30
// __VARIANT__ so that it's `false` when running against the new reconciler.
packages/shared/forks/ReactFeatureFlags.www.js
-1
@@ -26,7 +26,6 @@ export const {
26
deferRenderPhaseUpdateToNextBatch,
27
decoupleUpdatePriorityFromScheduler,
28
enableDebugTracing,
29
- enableSchedulingProfilerComponentStacks,
29
} = dynamicFeatureFlags;
30
31
// On WWW, __EXPERIMENTAL__ is used for a new modern build.