@samitouri / QOS-React-2 / commits / bf30e370a5

Remove User Timings (#18417)

Dan Abramov committed Mar 31, 2020 at 00:29 UTC bf30e370a503cc5787a0b20e9d50ece6a148d6c9
19 files changed +4 -1891
packages/react-dom/index.classic.fb.js
-3
@@ -7,7 +7,6 @@
7 * @flow
8 */
9
10 -import {addUserTimingListener} from 'shared/ReactFeatureFlags';
10 import {isEnabled} from './src/events/ReactDOMEventListener';
11
12 import {__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/client/ReactDOM';
@@ -17,8 +16,6 @@ Object.assign((__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any), {
16 ReactBrowserEventEmitter: {
17 isEnabled,
18 },
20 - // Perf experiment
21 - addUserTimingListener,
19 });
20
21 export {
packages/react-reconciler/src/ReactDebugFiberPerf.js deleted
-506
@@ -1,506 +0,0 @@
1 -/**
2 - * Copyright (c) Facebook, Inc. and its affiliates.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - *
7 - * @flow
8 - */
9 -
10 -import type {Fiber} from './ReactFiber';
11 -
12 -import {enableUserTimingAPI} from 'shared/ReactFeatureFlags';
13 -import getComponentName from 'shared/getComponentName';
14 -import {
15 - HostRoot,
16 - HostComponent,
17 - HostText,
18 - HostPortal,
19 - Fragment,
20 - ContextProvider,
21 - ContextConsumer,
22 - Mode,
23 - SuspenseComponent,
24 -} from './ReactWorkTags';
25 -
26 -type MeasurementPhase =
27 - | 'componentWillMount'
28 - | 'componentWillUnmount'
29 - | 'componentWillReceiveProps'
30 - | 'shouldComponentUpdate'
31 - | 'componentWillUpdate'
32 - | 'componentDidUpdate'
33 - | 'componentDidMount'
34 - | 'getChildContext'
35 - | 'getSnapshotBeforeUpdate';
36 -
37 -// Prefix measurements so that it's possible to filter them.
38 -// Longer prefixes are hard to read in DevTools.
39 -const reactEmoji = '\u269B';
40 -const warningEmoji = '\u26D4';
41 -const supportsUserTiming =
42 - typeof performance !== 'undefined' &&
43 - typeof performance.mark === 'function' &&
44 - typeof performance.clearMarks === 'function' &&
45 - typeof performance.measure === 'function' &&
46 - typeof performance.clearMeasures === 'function';
47 -
48 -// Keep track of current fiber so that we know the path to unwind on pause.
49 -// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
50 -let currentFiber: Fiber | null = null;
51 -// If we're in the middle of user code, which fiber and method is it?
52 -// Reusing `currentFiber` would be confusing for this because user code fiber
53 -// can change during commit phase too, but we don't need to unwind it (since
54 -// lifecycles in the commit phase don't resemble a tree).
55 -let currentPhase: MeasurementPhase | null = null;
56 -let currentPhaseFiber: Fiber | null = null;
57 -// Did lifecycle hook schedule an update? This is often a performance problem,
58 -// so we will keep track of it, and include it in the report.
59 -// Track commits caused by cascading updates.
60 -let isCommitting: boolean = false;
61 -let hasScheduledUpdateInCurrentCommit: boolean = false;
62 -let hasScheduledUpdateInCurrentPhase: boolean = false;
63 -let commitCountInCurrentWorkLoop: number = 0;
64 -let effectCountInCurrentCommit: number = 0;
65 -let isWaitingForCallback: boolean = false;
66 -// During commits, we only show a measurement once per method name
67 -// to avoid stretch the commit phase with measurement overhead.
68 -const labelsInCurrentCommit: Set<string> = new Set();
69 -
70 -const formatMarkName = (markName: string) => {
71 - return `${reactEmoji} ${markName}`;
72 -};
73 -
74 -const formatLabel = (label: string, warning: string | null) => {
75 - const prefix = warning ? `${warningEmoji} ` : `${reactEmoji} `;
76 - const suffix = warning ? ` Warning: ${warning}` : '';
77 - return `${prefix}${label}${suffix}`;
78 -};
79 -
80 -const beginMark = (markName: string) => {
81 - performance.mark(formatMarkName(markName));
82 -};
83 -
84 -const clearMark = (markName: string) => {
85 - performance.clearMarks(formatMarkName(markName));
86 -};
87 -
88 -const endMark = (label: string, markName: string, warning: string | null) => {
89 - const formattedMarkName = formatMarkName(markName);
90 - const formattedLabel = formatLabel(label, warning);
91 - try {
92 - performance.measure(formattedLabel, formattedMarkName);
93 - } catch (err) {
94 - // If previous mark was missing for some reason, this will throw.
95 - // This could only happen if React crashed in an unexpected place earlier.
96 - // Don't pile on with more errors.
97 - }
98 - // Clear marks immediately to avoid growing buffer.
99 - performance.clearMarks(formattedMarkName);
100 - performance.clearMeasures(formattedLabel);
101 -};
102 -
103 -const getFiberMarkName = (label: string, debugID: number) => {
104 - return `${label} (#${debugID})`;
105 -};
106 -
107 -const getFiberLabel = (
108 - componentName: string,
109 - isMounted: boolean,
110 - phase: MeasurementPhase | null,
111 -) => {
112 - if (phase === null) {
113 - // These are composite component total time measurements.
114 - return `${componentName} [${isMounted ? 'update' : 'mount'}]`;
115 - } else {
116 - // Composite component methods.
117 - return `${componentName}.${phase}`;
118 - }
119 -};
120 -
121 -const beginFiberMark = (
122 - fiber: Fiber,
123 - phase: MeasurementPhase | null,
124 -): boolean => {
125 - const componentName = getComponentName(fiber.type) || 'Unknown';
126 - const debugID = ((fiber._debugID: any): number);
127 - const isMounted = fiber.alternate !== null;
128 - const label = getFiberLabel(componentName, isMounted, phase);
129 -
130 - if (isCommitting && labelsInCurrentCommit.has(label)) {
131 - // During the commit phase, we don't show duplicate labels because
132 - // there is a fixed overhead for every measurement, and we don't
133 - // want to stretch the commit phase beyond necessary.
134 - return false;
135 - }
136 - labelsInCurrentCommit.add(label);
137 -
138 - const markName = getFiberMarkName(label, debugID);
139 - beginMark(markName);
140 - return true;
141 -};
142 -
143 -const clearFiberMark = (fiber: Fiber, phase: MeasurementPhase | null) => {
144 - const componentName = getComponentName(fiber.type) || 'Unknown';
145 - const debugID = ((fiber._debugID: any): number);
146 - const isMounted = fiber.alternate !== null;
147 - const label = getFiberLabel(componentName, isMounted, phase);
148 - const markName = getFiberMarkName(label, debugID);
149 - clearMark(markName);
150 -};
151 -
152 -const endFiberMark = (
153 - fiber: Fiber,
154 - phase: MeasurementPhase | null,
155 - warning: string | null,
156 -) => {
157 - const componentName = getComponentName(fiber.type) || 'Unknown';
158 - const debugID = ((fiber._debugID: any): number);
159 - const isMounted = fiber.alternate !== null;
160 - const label = getFiberLabel(componentName, isMounted, phase);
161 - const markName = getFiberMarkName(label, debugID);
162 - endMark(label, markName, warning);
163 -};
164 -
165 -const shouldIgnoreFiber = (fiber: Fiber): boolean => {
166 - // Host components should be skipped in the timeline.
167 - // We could check typeof fiber.type, but does this work with RN?
168 - switch (fiber.tag) {
169 - case HostRoot:
170 - case HostComponent:
171 - case HostText:
172 - case HostPortal:
173 - case Fragment:
174 - case ContextProvider:
175 - case ContextConsumer:
176 - case Mode:
177 - return true;
178 - default:
179 - return false;
180 - }
181 -};
182 -
183 -const clearPendingPhaseMeasurement = () => {
184 - if (currentPhase !== null && currentPhaseFiber !== null) {
185 - clearFiberMark(currentPhaseFiber, currentPhase);
186 - }
187 - currentPhaseFiber = null;
188 - currentPhase = null;
189 - hasScheduledUpdateInCurrentPhase = false;
190 -};
191 -
192 -const pauseTimers = () => {
193 - // Stops all currently active measurements so that they can be resumed
194 - // if we continue in a later deferred loop from the same unit of work.
195 - let fiber = currentFiber;
196 - while (fiber) {
197 - if (fiber._debugIsCurrentlyTiming) {
198 - endFiberMark(fiber, null, null);
199 - }
200 - fiber = fiber.return;
201 - }
202 -};
203 -
204 -const resumeTimersRecursively = (fiber: Fiber) => {
205 - if (fiber.return !== null) {
206 - resumeTimersRecursively(fiber.return);
207 - }
208 - if (fiber._debugIsCurrentlyTiming) {
209 - beginFiberMark(fiber, null);
210 - }
211 -};
212 -
213 -const resumeTimers = () => {
214 - // Resumes all measurements that were active during the last deferred loop.
215 - if (currentFiber !== null) {
216 - resumeTimersRecursively(currentFiber);
217 - }
218 -};
219 -
220 -export function recordEffect(): void {
221 - if (enableUserTimingAPI) {
222 - effectCountInCurrentCommit++;
223 - }
224 -}
225 -
226 -export function recordScheduleUpdate(): void {
227 - if (enableUserTimingAPI) {
228 - if (isCommitting) {
229 - hasScheduledUpdateInCurrentCommit = true;
230 - }
231 - if (
232 - currentPhase !== null &&
233 - currentPhase !== 'componentWillMount' &&
234 - currentPhase !== 'componentWillReceiveProps'
235 - ) {
236 - hasScheduledUpdateInCurrentPhase = true;
237 - }
238 - }
239 -}
240 -
241 -export function startRequestCallbackTimer(): void {
242 - if (enableUserTimingAPI) {
243 - if (supportsUserTiming && !isWaitingForCallback) {
244 - isWaitingForCallback = true;
245 - beginMark('(Waiting for async callback...)');
246 - }
247 - }
248 -}
249 -
250 -export function stopRequestCallbackTimer(didExpire: boolean): void {
251 - if (enableUserTimingAPI) {
252 - if (supportsUserTiming) {
253 - isWaitingForCallback = false;
254 - const warning = didExpire
255 - ? 'Update expired; will flush synchronously'
256 - : null;
257 - endMark(
258 - '(Waiting for async callback...)',
259 - '(Waiting for async callback...)',
260 - warning,
261 - );
262 - }
263 - }
264 -}
265 -
266 -export function startWorkTimer(fiber: Fiber): void {
267 - if (enableUserTimingAPI) {
268 - if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
269 - return;
270 - }
271 - // If we pause, this is the fiber to unwind from.
272 - currentFiber = fiber;
273 - if (!beginFiberMark(fiber, null)) {
274 - return;
275 - }
276 - fiber._debugIsCurrentlyTiming = true;
277 - }
278 -}
279 -
280 -export function cancelWorkTimer(fiber: Fiber): void {
281 - if (enableUserTimingAPI) {
282 - if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
283 - return;
284 - }
285 - // Remember we shouldn't complete measurement for this fiber.
286 - // Otherwise flamechart will be deep even for small updates.
287 - fiber._debugIsCurrentlyTiming = false;
288 - clearFiberMark(fiber, null);
289 - }
290 -}
291 -
292 -export function stopWorkTimer(fiber: Fiber): void {
293 - if (enableUserTimingAPI) {
294 - if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
295 - return;
296 - }
297 - // If we pause, its parent is the fiber to unwind from.
298 - currentFiber = fiber.return;
299 - if (!fiber._debugIsCurrentlyTiming) {
300 - return;
301 - }
302 - fiber._debugIsCurrentlyTiming = false;
303 - endFiberMark(fiber, null, null);
304 - }
305 -}
306 -
307 -export function stopFailedWorkTimer(fiber: Fiber): void {
308 - if (enableUserTimingAPI) {
309 - if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
310 - return;
311 - }
312 - // If we pause, its parent is the fiber to unwind from.
313 - currentFiber = fiber.return;
314 - if (!fiber._debugIsCurrentlyTiming) {
315 - return;
316 - }
317 - fiber._debugIsCurrentlyTiming = false;
318 - const warning =
319 - fiber.tag === SuspenseComponent
320 - ? 'Rendering was suspended'
321 - : 'An error was thrown inside this error boundary';
322 - endFiberMark(fiber, null, warning);
323 - }
324 -}
325 -
326 -export function startPhaseTimer(fiber: Fiber, phase: MeasurementPhase): void {
327 - if (enableUserTimingAPI) {
328 - if (!supportsUserTiming) {
329 - return;
330 - }
331 - clearPendingPhaseMeasurement();
332 - if (!beginFiberMark(fiber, phase)) {
333 - return;
334 - }
335 - currentPhaseFiber = fiber;
336 - currentPhase = phase;
337 - }
338 -}
339 -
340 -export function stopPhaseTimer(): void {
341 - if (enableUserTimingAPI) {
342 - if (!supportsUserTiming) {
343 - return;
344 - }
345 - if (currentPhase !== null && currentPhaseFiber !== null) {
346 - const warning = hasScheduledUpdateInCurrentPhase
347 - ? 'Scheduled a cascading update'
348 - : null;
349 - endFiberMark(currentPhaseFiber, currentPhase, warning);
350 - }
351 - currentPhase = null;
352 - currentPhaseFiber = null;
353 - }
354 -}
355 -
356 -export function startWorkLoopTimer(nextUnitOfWork: Fiber | null): void {
357 - if (enableUserTimingAPI) {
358 - currentFiber = nextUnitOfWork;
359 - if (!supportsUserTiming) {
360 - return;
361 - }
362 - commitCountInCurrentWorkLoop = 0;
363 - // This is top level call.
364 - // Any other measurements are performed within.
365 - beginMark('(React Tree Reconciliation)');
366 - // Resume any measurements that were in progress during the last loop.
367 - resumeTimers();
368 - }
369 -}
370 -
371 -export function stopWorkLoopTimer(
372 - interruptedBy: Fiber | null,
373 - didCompleteRoot: boolean,
374 -): void {
375 - if (enableUserTimingAPI) {
376 - if (!supportsUserTiming) {
377 - return;
378 - }
379 - let warning = null;
380 - if (interruptedBy !== null) {
381 - if (interruptedBy.tag === HostRoot) {
382 - warning = 'A top-level update interrupted the previous render';
383 - } else {
384 - const componentName = getComponentName(interruptedBy.type) || 'Unknown';
385 - warning = `An update to ${componentName} interrupted the previous render`;
386 - }
387 - } else if (commitCountInCurrentWorkLoop > 1) {
388 - warning = 'There were cascading updates';
389 - }
390 - commitCountInCurrentWorkLoop = 0;
391 - let label = didCompleteRoot
392 - ? '(React Tree Reconciliation: Completed Root)'
393 - : '(React Tree Reconciliation: Yielded)';
394 - // Pause any measurements until the next loop.
395 - pauseTimers();
396 - endMark(label, '(React Tree Reconciliation)', warning);
397 - }
398 -}
399 -
400 -export function startCommitTimer(): void {
401 - if (enableUserTimingAPI) {
402 - if (!supportsUserTiming) {
403 - return;
404 - }
405 - isCommitting = true;
406 - hasScheduledUpdateInCurrentCommit = false;
407 - labelsInCurrentCommit.clear();
408 - beginMark('(Committing Changes)');
409 - }
410 -}
411 -
412 -export function stopCommitTimer(): void {
413 - if (enableUserTimingAPI) {
414 - if (!supportsUserTiming) {
415 - return;
416 - }
417 -
418 - let warning = null;
419 - if (hasScheduledUpdateInCurrentCommit) {
420 - warning = 'Lifecycle hook scheduled a cascading update';
421 - } else if (commitCountInCurrentWorkLoop > 0) {
422 - warning = 'Caused by a cascading update in earlier commit';
423 - }
424 - hasScheduledUpdateInCurrentCommit = false;
425 - commitCountInCurrentWorkLoop++;
426 - isCommitting = false;
427 - labelsInCurrentCommit.clear();
428 -
429 - endMark('(Committing Changes)', '(Committing Changes)', warning);
430 - }
431 -}
432 -
433 -export function startCommitSnapshotEffectsTimer(): void {
434 - if (enableUserTimingAPI) {
435 - if (!supportsUserTiming) {
436 - return;
437 - }
438 - effectCountInCurrentCommit = 0;
439 - beginMark('(Committing Snapshot Effects)');
440 - }
441 -}
442 -
443 -export function stopCommitSnapshotEffectsTimer(): void {
444 - if (enableUserTimingAPI) {
445 - if (!supportsUserTiming) {
446 - return;
447 - }
448 - const count = effectCountInCurrentCommit;
449 - effectCountInCurrentCommit = 0;
450 - endMark(
451 - `(Committing Snapshot Effects: ${count} Total)`,
452 - '(Committing Snapshot Effects)',
453 - null,
454 - );
455 - }
456 -}
457 -
458 -export function startCommitHostEffectsTimer(): void {
459 - if (enableUserTimingAPI) {
460 - if (!supportsUserTiming) {
461 - return;
462 - }
463 - effectCountInCurrentCommit = 0;
464 - beginMark('(Committing Host Effects)');
465 - }
466 -}
467 -
468 -export function stopCommitHostEffectsTimer(): void {
469 - if (enableUserTimingAPI) {
470 - if (!supportsUserTiming) {
471 - return;
472 - }
473 - const count = effectCountInCurrentCommit;
474 - effectCountInCurrentCommit = 0;
475 - endMark(
476 - `(Committing Host Effects: ${count} Total)`,
477 - '(Committing Host Effects)',
478 - null,
479 - );
480 - }
481 -}
482 -
483 -export function startCommitLifeCyclesTimer(): void {
484 - if (enableUserTimingAPI) {
485 - if (!supportsUserTiming) {
486 - return;
487 - }
488 - effectCountInCurrentCommit = 0;
489 - beginMark('(Calling Lifecycle Methods)');
490 - }
491 -}
492 -
493 -export function stopCommitLifeCyclesTimer(): void {
494 - if (enableUserTimingAPI) {
495 - if (!supportsUserTiming) {
496 - return;
497 - }
498 - const count = effectCountInCurrentCommit;
499 - effectCountInCurrentCommit = 0;
500 - endMark(
501 - `(Calling Lifecycle Methods: ${count} Total)`,
502 - '(Calling Lifecycle Methods)',
503 - null,
504 - );
505 - }
506 -}
packages/react-reconciler/src/ReactFiber.js
+4 -15
@@ -31,7 +31,6 @@ import invariant from 'shared/invariant';
31 import {
32 enableProfilerTimer,
33 enableFundamentalAPI,
34 - enableUserTimingAPI,
34 enableScopeAPI,
35 enableBlocksAPI,
36 throwEarlyForMysteriousError,
@@ -324,14 +323,9 @@ function FiberNode(
323 this.treeBaseDuration = 0;
324 }
325
327 - // This is normally DEV-only except www when it adds listeners.
328 - // TODO: remove the User Timing integration in favor of Root Events.
329 - if (enableUserTimingAPI) {
330 - this._debugID = debugCounter++;
331 - this._debugIsCurrentlyTiming = false;
332 - }
333 -
326 if (__DEV__) {
327 + // This isn't directly used but is handy for debugging internals:
328 + this._debugID = debugCounter++;
329 this._debugSource = null;
330 this._debugOwner = null;
331 this._debugNeedsRemount = false;
@@ -419,9 +413,7 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber {
413
414 if (__DEV__) {
415 // DEV-only fields
422 - if (enableUserTimingAPI) {
423 - workInProgress._debugID = current._debugID;
424 - }
416 + workInProgress._debugID = current._debugID;
417 workInProgress._debugSource = current._debugSource;
418 workInProgress._debugOwner = current._debugOwner;
419 workInProgress._debugHookTypes = current._debugHookTypes;
@@ -968,10 +960,7 @@ export function assignFiberPropertiesInDEV(
960 target.selfBaseDuration = source.selfBaseDuration;
961 target.treeBaseDuration = source.treeBaseDuration;
962 }
971 - if (enableUserTimingAPI) {
972 - target._debugID = source._debugID;
973 - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
974 - }
963 + target._debugID = source._debugID;
964 target._debugSource = source._debugSource;
965 target._debugOwner = source._debugOwner;
966 target._debugNeedsRemount = source._debugNeedsRemount;
packages/react-reconciler/src/ReactFiberBeginWork.js
-7
@@ -79,7 +79,6 @@ import {
79 getCurrentFiberOwnerNameInDevOrNull,
80 setIsRendering,
81 } from './ReactCurrentFiber';
82 -import {startWorkTimer, cancelWorkTimer} from './ReactDebugFiberPerf';
82 import {
83 resolveFunctionForHotReloading,
84 resolveForwardRefForHotReloading,
@@ -1128,9 +1127,6 @@ function mountLazyComponent(
1127 }
1128
1129 const props = workInProgress.pendingProps;
1131 - // We can't start a User Timing measurement with correct label yet.
1132 - // Cancel and resume right after we know the tag.
1133 - cancelWorkTimer(workInProgress);
1130 let lazyComponent: LazyComponentType<any, any> = elementType;
1131 let payload = lazyComponent._payload;
1132 let init = lazyComponent._init;
@@ -1138,7 +1134,6 @@ function mountLazyComponent(
1134 // Store the unwrapped component in the type.
1135 workInProgress.type = Component;
1136 const resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component));
1141 - startWorkTimer(workInProgress);
1137 const resolvedProps = resolveDefaultProps(Component, props);
1138 let child;
1139 switch (resolvedTag) {
@@ -2886,8 +2881,6 @@ function bailoutOnAlreadyFinishedWork(
2881 workInProgress: Fiber,
2882 renderExpirationTime: ExpirationTime,
2883 ): Fiber | null {
2889 - cancelWorkTimer(workInProgress);
2890 -
2884 if (current !== null) {
2885 // Reuse previous dependencies
2886 workInProgress.dependencies = current.dependencies;
packages/react-reconciler/src/ReactFiberClassComponent.js
-12
@@ -26,7 +26,6 @@ import getComponentName from 'shared/getComponentName';
26 import invariant from 'shared/invariant';
27 import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
28
29 -import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
29 import {resolveDefaultProps} from './ReactFiberLazyComponent';
30 import {StrictMode} from './ReactTypeOfMode';
31
@@ -271,13 +270,11 @@ function checkShouldComponentUpdate(
270 instance.shouldComponentUpdate(newProps, newState, nextContext);
271 }
272 }
274 - startPhaseTimer(workInProgress, 'shouldComponentUpdate');
273 const shouldUpdate = instance.shouldComponentUpdate(
274 newProps,
275 newState,
276 nextContext,
277 );
280 - stopPhaseTimer();
278
279 if (__DEV__) {
280 if (shouldUpdate === undefined) {
@@ -705,7 +702,6 @@ function constructClassInstance(
702 }
703
704 function callComponentWillMount(workInProgress, instance) {
708 - startPhaseTimer(workInProgress, 'componentWillMount');
705 const oldState = instance.state;
706
707 if (typeof instance.componentWillMount === 'function') {
@@ -715,8 +711,6 @@ function callComponentWillMount(workInProgress, instance) {
711 instance.UNSAFE_componentWillMount();
712 }
713
718 - stopPhaseTimer();
719 -
714 if (oldState !== instance.state) {
715 if (__DEV__) {
716 console.error(
@@ -737,14 +731,12 @@ function callComponentWillReceiveProps(
731 nextContext,
732 ) {
733 const oldState = instance.state;
740 - startPhaseTimer(workInProgress, 'componentWillReceiveProps');
734 if (typeof instance.componentWillReceiveProps === 'function') {
735 instance.componentWillReceiveProps(newProps, nextContext);
736 }
737 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
738 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
739 }
747 - stopPhaseTimer();
740
741 if (instance.state !== oldState) {
742 if (__DEV__) {
@@ -961,14 +953,12 @@ function resumeMountClassInstance(
953 (typeof instance.UNSAFE_componentWillMount === 'function' ||
954 typeof instance.componentWillMount === 'function')
955 ) {
964 - startPhaseTimer(workInProgress, 'componentWillMount');
956 if (typeof instance.componentWillMount === 'function') {
957 instance.componentWillMount();
958 }
959 if (typeof instance.UNSAFE_componentWillMount === 'function') {
960 instance.UNSAFE_componentWillMount();
961 }
971 - stopPhaseTimer();
962 }
963 if (typeof instance.componentDidMount === 'function') {
964 workInProgress.effectTag |= Update;
@@ -1113,14 +1103,12 @@ function updateClassInstance(
1103 (typeof instance.UNSAFE_componentWillUpdate === 'function' ||
1104 typeof instance.componentWillUpdate === 'function')
1105 ) {
1116 - startPhaseTimer(workInProgress, 'componentWillUpdate');
1106 if (typeof instance.componentWillUpdate === 'function') {
1107 instance.componentWillUpdate(newProps, newState, nextContext);
1108 }
1109 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
1110 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
1111 }
1123 - stopPhaseTimer();
1112 }
1113 if (typeof instance.componentDidUpdate === 'function') {
1114 workInProgress.effectTag |= Update;
packages/react-reconciler/src/ReactFiberCommitWork.js
-9
@@ -74,7 +74,6 @@ import getComponentName from 'shared/getComponentName';
74 import invariant from 'shared/invariant';
75
76 import {onCommitUnmount} from './ReactFiberDevToolsHook';
77 -import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
77 import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';
78 import {logCapturedError} from './ReactFiberErrorLogger';
79 import {resolveDefaultProps} from './ReactFiberLazyComponent';
@@ -182,7 +181,6 @@ export function logError(boundary: Fiber, errorInfo: CapturedValue<mixed>) {
181 }
182
183 const callComponentWillUnmountWithTimer = function(current, instance) {
185 - startPhaseTimer(current, 'componentWillUnmount');
184 instance.props = current.memoizedProps;
185 instance.state = current.memoizedState;
186 if (
@@ -199,7 +197,6 @@ const callComponentWillUnmountWithTimer = function(current, instance) {
197 } else {
198 instance.componentWillUnmount();
199 }
202 - stopPhaseTimer();
200 };
201
202 // Capture errors so they don't interrupt unmounting.
@@ -280,7 +277,6 @@ function commitBeforeMutationLifeCycles(
277 if (current !== null) {
278 const prevProps = current.memoizedProps;
279 const prevState = current.memoizedState;
283 - startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
280 const instance = finishedWork.stateNode;
281 // We could update instance props and state here,
282 // but instead we rely on them being set during last render.
@@ -330,7 +326,6 @@ function commitBeforeMutationLifeCycles(
326 }
327 }
328 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
333 - stopPhaseTimer();
329 }
330 }
331 return;
@@ -580,7 +575,6 @@ function commitLifeCycles(
575 const instance = finishedWork.stateNode;
576 if (finishedWork.effectTag & Update) {
577 if (current === null) {
583 - startPhaseTimer(finishedWork, 'componentDidMount');
578 // We could update instance props and state here,
579 // but instead we rely on them being set during last render.
580 // TODO: revisit this when we implement resuming.
@@ -625,14 +619,12 @@ function commitLifeCycles(
619 } else {
620 instance.componentDidMount();
621 }
628 - stopPhaseTimer();
622 } else {
623 const prevProps =
624 finishedWork.elementType === finishedWork.type
625 ? current.memoizedProps
626 : resolveDefaultProps(finishedWork.type, current.memoizedProps);
627 const prevState = current.memoizedState;
635 - startPhaseTimer(finishedWork, 'componentDidUpdate');
628 // We could update instance props and state here,
629 // but instead we rely on them being set during last render.
630 // TODO: revisit this when we implement resuming.
@@ -685,7 +677,6 @@ function commitLifeCycles(
677 instance.__reactInternalSnapshotBeforeUpdate,
678 );
679 }
688 - stopPhaseTimer();
680 }
681 }
682 const updateQueue = finishedWork.updateQueue;
packages/react-reconciler/src/ReactFiberContext.js
-3
@@ -17,7 +17,6 @@ import getComponentName from 'shared/getComponentName';
17 import invariant from 'shared/invariant';
18 import checkPropTypes from 'shared/checkPropTypes';
19
20 -import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
20 import {createCursor, push, pop} from './ReactFiberStack';
21
22 let warnedAboutMissingGetChildContext;
@@ -203,9 +202,7 @@ function processChildContext(
202 }
203
204 let childContext;
206 - startPhaseTimer(fiber, 'getChildContext');
205 childContext = instance.getChildContext();
208 - stopPhaseTimer();
206 for (let contextKey in childContext) {
207 invariant(
208 contextKey in childContextTypes,
packages/react-reconciler/src/ReactFiberWorkLoop.js
-85
@@ -21,7 +21,6 @@ import {
21 warnAboutDeprecatedLifecycles,
22 deferPassiveEffectCleanupDuringUnmount,
23 runAllPassiveEffectDestroysBeforeCreates,
24 - enableUserTimingAPI,
24 enableSuspenseServerRenderer,
25 replayFailedUnitOfWorkWithInvokeGuardedCallback,
26 enableProfilerTimer,
@@ -167,23 +166,6 @@ import {
166 setCurrentFiber as setCurrentDebugFiberInDEV,
167 getStackByFiberInDevAndProd,
168 } from './ReactCurrentFiber';
170 -import {
171 - recordEffect,
172 - recordScheduleUpdate,
173 - startWorkTimer,
174 - stopWorkTimer,
175 - stopFailedWorkTimer,
176 - startWorkLoopTimer,
177 - stopWorkLoopTimer,
178 - startCommitTimer,
179 - stopCommitTimer,
180 - startCommitSnapshotEffectsTimer,
181 - stopCommitSnapshotEffectsTimer,
182 - startCommitHostEffectsTimer,
183 - stopCommitHostEffectsTimer,
184 - startCommitLifeCyclesTimer,
185 - stopCommitLifeCyclesTimer,
186 -} from './ReactDebugFiberPerf';
169 import {
170 invokeGuardedCallback,
171 hasCaughtError,
@@ -275,8 +257,6 @@ let rootWithNestedUpdates: FiberRoot | null = null;
257 const NESTED_PASSIVE_UPDATE_LIMIT = 50;
258 let nestedPassiveUpdateCount: number = 0;
259
278 -let interruptedBy: Fiber | null = null;
279 -
260 // Marks the need to reschedule pending interactions at these expiration times
261 // during the commit phase. This enables them to be traced across components
262 // that spawn new work during render. E.g. hidden boundaries, suspended SSR
@@ -397,9 +377,6 @@ export function scheduleUpdateOnFiber(
377 return;
378 }
379
400 - checkForInterruption(fiber, expirationTime);
401 - recordScheduleUpdate();
402 -
380 // TODO: computeExpirationForFiber also reads the priority. Pass the
381 // priority as an argument to that function and this one.
382 const priorityLevel = getCurrentPriorityLevel();
@@ -1410,7 +1387,6 @@ function renderRootSync(root, expirationTime) {
1387 }
1388
1389 const prevInteractions = pushInteractions(root);
1413 - startWorkLoopTimer(workInProgress);
1390 do {
1391 try {
1392 workLoopSync();
@@ -1436,8 +1412,6 @@ function renderRootSync(root, expirationTime) {
1412 );
1413 }
1414
1439 - stopFinishedWorkLoopTimer();
1440 -
1415 // Set this to null to indicate there's no in-progress render.
1416 workInProgressRoot = null;
1417
@@ -1466,7 +1440,6 @@ function renderRootConcurrent(root, expirationTime) {
1440 }
1441
1442 const prevInteractions = pushInteractions(root);
1469 - startWorkLoopTimer(workInProgress);
1443 do {
1444 try {
1445 workLoopConcurrent();
@@ -1486,12 +1459,9 @@ function renderRootConcurrent(root, expirationTime) {
1459 // Check if the tree has completed.
1460 if (workInProgress !== null) {
1461 // Still work remaining.
1489 - stopInterruptedWorkLoopTimer();
1462 return RootIncomplete;
1463 } else {
1464 // Completed the tree.
1493 - stopFinishedWorkLoopTimer();
1494 -
1465 // Set this to null to indicate there's no in-progress render.
1466 workInProgressRoot = null;
1467
@@ -1513,8 +1483,6 @@ function performUnitOfWork(unitOfWork: Fiber): Fiber | null {
1483 // nothing should rely on this, but relying on it here means that we don't
1484 // need an additional field on the work in progress.
1485 const current = unitOfWork.alternate;
1516 -
1517 - startWorkTimer(unitOfWork);
1486 setCurrentDebugFiberInDEV(unitOfWork);
1487
1488 let next;
@@ -1563,7 +1531,6 @@ function completeUnitOfWork(unitOfWork: Fiber): Fiber | null {
1531 // Update render duration assuming we didn't error.
1532 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
1533 }
1566 - stopWorkTimer(workInProgress);
1534 resetCurrentDebugFiberInDEV();
1535 resetChildExpirationTime(workInProgress);
1536
@@ -1640,13 +1607,9 @@ function completeUnitOfWork(unitOfWork: Fiber): Fiber | null {
1607 // back here again.
1608 // Since we're restarting, remove anything that is not a host effect
1609 // from the effect tag.
1643 - // TODO: The name stopFailedWorkTimer is misleading because Suspense
1644 - // also captures and restarts.
1645 - stopFailedWorkTimer(workInProgress);
1610 next.effectTag &= HostEffectMask;
1611 return next;
1612 }
1649 - stopWorkTimer(workInProgress);
1613
1614 if (returnFiber !== null) {
1615 // Mark the parent fiber as incomplete and clear its effect list.
@@ -1792,8 +1755,6 @@ function commitRootImpl(root, renderPriorityLevel) {
1755 root.callbackPriority = NoPriority;
1756 root.nextKnownPendingLevel = NoWork;
1757
1795 - startCommitTimer();
1796 -
1758 // Update the first and last pending times on this root. The new first
1759 // pending time is whatever is left on the root fiber.
1760 const remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(
@@ -1849,7 +1810,6 @@ function commitRootImpl(root, renderPriorityLevel) {
1810 // The first phase a "before mutation" phase. We use this phase to read the
1811 // state of the host tree right before we mutate it. This is where
1812 // getSnapshotBeforeUpdate is called.
1852 - startCommitSnapshotEffectsTimer();
1813 prepareForCommit(root.containerInfo);
1814 nextEffect = firstEffect;
1815 do {
@@ -1871,7 +1831,6 @@ function commitRootImpl(root, renderPriorityLevel) {
1831 }
1832 }
1833 } while (nextEffect !== null);
1874 - stopCommitSnapshotEffectsTimer();
1834
1835 if (enableProfilerTimer) {
1836 // Mark the current commit time to be shared by all Profilers in this
@@ -1880,7 +1839,6 @@ function commitRootImpl(root, renderPriorityLevel) {
1839 }
1840
1841 // The next phase is the mutation phase, where we mutate the host tree.
1883 - startCommitHostEffectsTimer();
1842 nextEffect = firstEffect;
1843 do {
1844 if (__DEV__) {
@@ -1907,7 +1865,6 @@ function commitRootImpl(root, renderPriorityLevel) {
1865 }
1866 }
1867 } while (nextEffect !== null);
1910 - stopCommitHostEffectsTimer();
1868 resetAfterCommit(root.containerInfo);
1869
1870 // The work-in-progress tree is now the current tree. This must come after
@@ -1919,7 +1876,6 @@ function commitRootImpl(root, renderPriorityLevel) {
1876 // The next phase is the layout phase, where we call effects that read
1877 // the host tree after it's been mutated. The idiomatic use case for this is
1878 // layout, but class component lifecycles also fire here for legacy reasons.
1922 - startCommitLifeCyclesTimer();
1879 nextEffect = firstEffect;
1880 do {
1881 if (__DEV__) {
@@ -1946,7 +1902,6 @@ function commitRootImpl(root, renderPriorityLevel) {
1902 }
1903 }
1904 } while (nextEffect !== null);
1949 - stopCommitLifeCyclesTimer();
1905
1906 nextEffect = null;
1907
@@ -1964,19 +1919,11 @@ function commitRootImpl(root, renderPriorityLevel) {
1919 // Measure these anyway so the flamegraph explicitly shows that there were
1920 // no effects.
1921 // TODO: Maybe there's a better way to report this.
1967 - startCommitSnapshotEffectsTimer();
1968 - stopCommitSnapshotEffectsTimer();
1922 if (enableProfilerTimer) {
1923 recordCommitTime();
1924 }
1972 - startCommitHostEffectsTimer();
1973 - stopCommitHostEffectsTimer();
1974 - startCommitLifeCyclesTimer();
1975 - stopCommitLifeCyclesTimer();
1925 }
1926
1978 - stopCommitTimer();
1979 -
1927 const rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
1928
1929 if (rootDoesHavePassiveEffects) {
@@ -2075,7 +2022,6 @@ function commitBeforeMutationEffects() {
2022 const effectTag = nextEffect.effectTag;
2023 if ((effectTag & Snapshot) !== NoEffect) {
2024 setCurrentDebugFiberInDEV(nextEffect);
2078 - recordEffect();
2025
2026 const current = nextEffect.alternate;
2027 commitBeforeMutationEffectOnFiber(current, nextEffect);
@@ -2166,9 +2112,6 @@ function commitMutationEffects(root: FiberRoot, renderPriorityLevel) {
2112 }
2113 }
2114
2169 - // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
2170 - recordEffect();
2171 -
2115 resetCurrentDebugFiberInDEV();
2116 nextEffect = nextEffect.nextEffect;
2117 }
@@ -2185,7 +2128,6 @@ function commitLayoutEffects(
2128 const effectTag = nextEffect.effectTag;
2129
2130 if (effectTag & (Update | Callback)) {
2188 - recordEffect();
2131 const current = nextEffect.alternate;
2132 commitLayoutEffectOnFiber(
2133 root,
@@ -2196,7 +2138,6 @@ function commitLayoutEffects(
2138 }
2139
2140 if (effectTag & Ref) {
2199 - recordEffect();
2141 commitAttachRef(nextEffect);
2142 }
2143
@@ -2755,32 +2696,6 @@ function flushRenderPhaseStrictModeWarningsInDEV() {
2696 }
2697 }
2698
2758 -function stopFinishedWorkLoopTimer() {
2759 - const didCompleteRoot = true;
2760 - stopWorkLoopTimer(interruptedBy, didCompleteRoot);
2761 - interruptedBy = null;
2762 -}
2763 -
2764 -function stopInterruptedWorkLoopTimer() {
2765 - // TODO: Track which fiber caused the interruption.
2766 - const didCompleteRoot = false;
2767 - stopWorkLoopTimer(interruptedBy, didCompleteRoot);
2768 - interruptedBy = null;
2769 -}
2770 -
2771 -function checkForInterruption(
2772 - fiberThatReceivedUpdate: Fiber,
2773 - updateExpirationTime: ExpirationTime,
2774 -) {
2775 - if (
2776 - enableUserTimingAPI &&
2777 - workInProgressRoot !== null &&
2778 - updateExpirationTime > renderExpirationTime
2779 - ) {
2780 - interruptedBy = fiberThatReceivedUpdate;
2781 - }
2782 -}
2783 -
2699 let didWarnStateUpdateForUnmountedComponent: Set<string> | null = null;
2700 function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
2701 if (__DEV__) {
packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js deleted
-683
@@ -1,683 +0,0 @@
1 -/**
2 - * Copyright (c) Facebook, Inc. and its affiliates.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - *
7 - * @emails react-core
8 - * @jest-environment node
9 - */
10 -
11 -'use strict';
12 -
13 -describe('ReactDebugFiberPerf', () => {
14 - let React;
15 - let ReactNoop;
16 - let Scheduler;
17 - let PropTypes;
18 -
19 - let root;
20 - let activeMeasure;
21 - let knownMarks;
22 - let knownMeasures;
23 - let comments;
24 -
25 - function resetFlamechart() {
26 - root = {
27 - children: [],
28 - indent: -1,
29 - markName: null,
30 - label: null,
31 - parent: null,
32 - toString() {
33 - return this.children.map(c => c.toString()).join('\n');
34 - },
35 - };
36 - activeMeasure = root;
37 - knownMarks = new Set();
38 - knownMeasures = new Set();
39 - comments = [];
40 - }
41 -
42 - function addComment(comment) {
43 - comments.push(comment);
44 - }
45 -
46 - function getFlameChart() {
47 - // Make sure we unwind the measurement stack every time.
48 - expect(activeMeasure.indent).toBe(-1);
49 - expect(activeMeasure).toBe(root);
50 - // We should always clean them up because browsers
51 - // buffer user timing measurements forever.
52 - expect(knownMarks.size).toBe(0);
53 - expect(knownMeasures.size).toBe(0);
54 - return root.toString();
55 - }
56 -
57 - function createUserTimingPolyfill() {
58 - // This is not a true polyfill, but it gives us enough
59 - // to capture measurements in a readable tree-like output.
60 - // Reference: https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API
61 - return {
62 - mark(markName) {
63 - const measure = {
64 - children: [],
65 - indent: activeMeasure.indent + 1,
66 - markName: markName,
67 - // Will be assigned on measure() call:
68 - label: null,
69 - parent: activeMeasure,
70 - comments,
71 - toString() {
72 - return (
73 - [
74 - ...this.comments.map(c => ' '.repeat(this.indent) + '// ' + c),
75 - ' '.repeat(this.indent) + this.label,
76 - ...this.children.map(c => c.toString()),
77 - ].join('\n') +
78 - // Extra newline after each root reconciliation
79 - (this.indent === 0 ? '\n' : '')
80 - );
81 - },
82 - };
83 - comments = [];
84 - // Step one level deeper
85 - activeMeasure.children.push(measure);
86 - activeMeasure = measure;
87 - knownMarks.add(markName);
88 - },
89 - // We don't use the overload with three arguments.
90 - measure(label, markName) {
91 - if (markName !== activeMeasure.markName) {
92 - // Fail the test.
93 - console.error(
94 - 'Unexpected measure() call: "%s". Active mark is "%s".',
95 - markName,
96 - activeMeasure.markName,
97 - );
98 - // This exception will be caught and ignored
99 - // because in the real implementation, we don't want
100 - // to spam the console due to a React bug.
101 - throw new Error('Unexpected measure() call.');
102 - }
103 - // Step one level up
104 - activeMeasure.label = label;
105 - activeMeasure = activeMeasure.parent;
106 - knownMeasures.add(label);
107 - },
108 - clearMarks(markName) {
109 - if (markName === activeMeasure.markName) {
110 - // Step one level up if we're in this measure
111 - activeMeasure = activeMeasure.parent;
112 - activeMeasure.children.length--;
113 - }
114 - knownMarks.delete(markName);
115 - },
116 - clearMeasures(label) {
117 - knownMeasures.delete(label);
118 - },
119 - };
120 - }
121 -
122 - function Parent(props) {
123 - return <div>{props.children}</div>;
124 - }
125 -
126 - function Child(props) {
127 - return <div>{props.children}</div>;
128 - }
129 -
130 - beforeEach(() => {
131 - jest.resetModules();
132 - resetFlamechart();
133 - global.performance = createUserTimingPolyfill();
134 -
135 - require('shared/ReactFeatureFlags').enableUserTimingAPI = true;
136 - require('shared/ReactFeatureFlags').enableProfilerTimer = false;
137 - require('shared/ReactFeatureFlags').replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
138 - require('shared/ReactFeatureFlags').debugRenderPhaseSideEffectsForStrictMode = false;
139 - require('scheduler/src/SchedulerFeatureFlags').enableProfiling = false;
140 -
141 - // Import after the polyfill is set up:
142 - React = require('react');
143 - ReactNoop = require('react-noop-renderer');
144 - Scheduler = require('scheduler');
145 - PropTypes = require('prop-types');
146 - });
147 -
148 - afterEach(() => {
149 - delete global.performance;
150 - });
151 -
152 - it('measures a simple reconciliation', () => {
153 - ReactNoop.render(
154 - <Parent>
155 - <Child />
156 - </Parent>,
157 - );
158 - addComment('Mount');
159 - expect(Scheduler).toFlushWithoutYielding();
160 -
161 - ReactNoop.render(
162 - <Parent>
163 - <Child />
164 - </Parent>,
165 - );
166 - addComment('Update');
167 - expect(Scheduler).toFlushWithoutYielding();
168 -
169 - ReactNoop.render(null);
170 - addComment('Unmount');
171 - expect(Scheduler).toFlushWithoutYielding();
172 -
173 - expect(getFlameChart()).toMatchSnapshot();
174 - });
175 -
176 - it('properly displays the forwardRef component in measurements', () => {
177 - const AnonymousForwardRef = React.forwardRef((props, ref) => (
178 - <Child {...props} ref={ref} />
179 - ));
180 - const NamedForwardRef = React.forwardRef(function refForwarder(props, ref) {
181 - return <Child {...props} ref={ref} />;
182 - });
183 - function notImportant(props, ref) {
184 - return <Child {...props} ref={ref} />;
185 - }
186 - notImportant.displayName = 'OverriddenName';
187 - const DisplayNamedForwardRef = React.forwardRef(notImportant);
188 -
189 - ReactNoop.render(
190 - <Parent>
191 - <AnonymousForwardRef />
192 - <NamedForwardRef />
193 - <DisplayNamedForwardRef />
194 - </Parent>,
195 - );
196 - addComment('Mount');
197 - expect(Scheduler).toFlushWithoutYielding();
198 -
199 - expect(getFlameChart()).toMatchSnapshot();
200 - });
201 -
202 - it('does not include StrictMode or Profiler components in measurements', () => {
203 - ReactNoop.render(
204 - <React.Profiler id="test" onRender={jest.fn()}>
205 - <React.StrictMode>
206 - <Parent>
207 - <Child />
208 - </Parent>
209 - </React.StrictMode>
210 - </React.Profiler>,
211 - );
212 - addComment('Mount');
213 - expect(Scheduler).toFlushWithoutYielding();
214 -
215 - expect(getFlameChart()).toMatchSnapshot();
216 - });
217 -
218 - it('does not include context provider or consumer in measurements', () => {
219 - const {Consumer, Provider} = React.createContext(true);
220 -
221 - ReactNoop.render(
222 - <Provider value={false}>
223 - <Parent>
224 - <Consumer>{value => <Child value={value} />}</Consumer>
225 - </Parent>
226 - </Provider>,
227 - );
228 - addComment('Mount');
229 - expect(Scheduler).toFlushWithoutYielding();
230 -
231 - expect(getFlameChart()).toMatchSnapshot();
232 - });
233 -
234 - it('skips parents during setState', () => {
235 - class A extends React.Component {
236 - render() {
237 - return <div>{this.props.children}</div>;
238 - }
239 - }
240 -
241 - class B extends React.Component {
242 - render() {
243 - return <div>{this.props.children}</div>;
244 - }
245 - }
246 -
247 - let a;
248 - let b;
249 - ReactNoop.render(
250 - <Parent>
251 - <Parent>
252 - <Parent>
253 - <A ref={inst => (a = inst)} />
254 - </Parent>
255 - </Parent>
256 - <Parent>
257 - <B ref={inst => (b = inst)} />
258 - </Parent>
259 - </Parent>,
260 - );
261 - expect(Scheduler).toFlushWithoutYielding();
262 - resetFlamechart();
263 -
264 - a.setState({});
265 - b.setState({});
266 - addComment('Should include just A and B, no Parents');
267 - expect(Scheduler).toFlushWithoutYielding();
268 - expect(getFlameChart()).toMatchSnapshot();
269 - });
270 -
271 - it('warns on cascading renders from setState', () => {
272 - class Cascading extends React.Component {
273 - componentDidMount() {
274 - this.setState({});
275 - }
276 - render() {
277 - return <div>{this.props.children}</div>;
278 - }
279 - }
280 -
281 - ReactNoop.render(
282 - <Parent>
283 - <Cascading />
284 - </Parent>,
285 - );
286 - addComment('Should print a warning');
287 - expect(Scheduler).toFlushWithoutYielding();
288 - expect(getFlameChart()).toMatchSnapshot();
289 - });
290 -
291 - it('warns on cascading renders from top-level render', () => {
292 - class Cascading extends React.Component {
293 - componentDidMount() {
294 - ReactNoop.renderToRootWithID(<Child />, 'b');
295 - addComment('Scheduling another root from componentDidMount');
296 - }
297 - render() {
298 - return <div>{this.props.children}</div>;
299 - }
300 - }
301 -
302 - ReactNoop.renderToRootWithID(<Cascading />, 'a');
303 - addComment('Rendering the first root');
304 - expect(Scheduler).toFlushWithoutYielding();
305 - expect(getFlameChart()).toMatchSnapshot();
306 - });
307 -
308 - it('does not treat setState from cWM or cWRP as cascading', () => {
309 - class NotCascading extends React.Component {
310 - UNSAFE_componentWillMount() {
311 - this.setState({});
312 - }
313 - UNSAFE_componentWillReceiveProps() {
314 - this.setState({});
315 - }
316 - render() {
317 - return <div>{this.props.children}</div>;
318 - }
319 - }
320 -
321 - ReactNoop.render(
322 - <Parent>
323 - <NotCascading />
324 - </Parent>,
325 - );
326 - addComment('Should not print a warning');
327 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
328 - [
329 - 'Using UNSAFE_componentWillMount in strict mode is not recommended',
330 - 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended',
331 - ],
332 - {withoutStack: true},
333 - );
334 - ReactNoop.render(
335 - <Parent>
336 - <NotCascading />
337 - </Parent>,
338 - );
339 - addComment('Should not print a warning');
340 - expect(Scheduler).toFlushWithoutYielding();
341 - expect(getFlameChart()).toMatchSnapshot();
342 - });
343 -
344 - it('captures all lifecycles', () => {
345 - class AllLifecycles extends React.Component {
346 - static childContextTypes = {
347 - foo: PropTypes.any,
348 - };
349 - shouldComponentUpdate() {
350 - return true;
351 - }
352 - getChildContext() {
353 - return {foo: 42};
354 - }
355 - UNSAFE_componentWillMount() {}
356 - componentDidMount() {}
357 - UNSAFE_componentWillReceiveProps() {}
358 - UNSAFE_componentWillUpdate() {}
359 - componentDidUpdate() {}
360 - componentWillUnmount() {}
361 - render() {
362 - return <div />;
363 - }
364 - }
365 - ReactNoop.render(<AllLifecycles />);
366 - addComment('Mount');
367 - expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev(
368 - [
369 - 'Using UNSAFE_componentWillMount in strict mode is not recommended',
370 - 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended',
371 - 'Using UNSAFE_componentWillUpdate in strict mode is not recommended',
372 - 'Legacy context API has been detected within a strict-mode tree',
373 - ],
374 - {withoutStack: 3},
375 - );
376 - ReactNoop.render(<AllLifecycles />);
377 - addComment('Update');
378 - expect(Scheduler).toFlushWithoutYielding();
379 - ReactNoop.render(null);
380 - addComment('Unmount');
381 - expect(Scheduler).toFlushWithoutYielding();
382 - expect(getFlameChart()).toMatchSnapshot();
383 - });
384 -
385 - it('measures deprioritized work', () => {
386 - addComment('Flush the parent');
387 - ReactNoop.flushSync(() => {
388 - ReactNoop.render(
389 - <Parent>
390 - <div hidden={true}>
391 - <Child />
392 - </div>
393 - </Parent>,
394 - );
395 - });
396 - addComment('Flush the child');
397 - expect(Scheduler).toFlushWithoutYielding();
398 - expect(getFlameChart()).toMatchSnapshot();
399 - });
400 -
401 - it('measures deferred work in chunks', () => {
402 - class A extends React.Component {
403 - render() {
404 - Scheduler.unstable_yieldValue('A');
405 - return <div>{this.props.children}</div>;
406 - }
407 - }
408 -
409 - class B extends React.Component {
410 - render() {
411 - Scheduler.unstable_yieldValue('B');
412 - return <div>{this.props.children}</div>;
413 - }
414 - }
415 -
416 - class C extends React.Component {
417 - render() {
418 - Scheduler.unstable_yieldValue('C');
419 - return <div>{this.props.children}</div>;
420 - }
421 - }
422 -
423 - ReactNoop.render(
424 - <Parent>
425 - <A>
426 - <Child />
427 - </A>
428 - <B>
429 - <Child />
430 - </B>
431 - <C>
432 - <Child />
433 - </C>
434 - </Parent>,
435 - );
436 - addComment('Start rendering through B');
437 - expect(Scheduler).toFlushAndYieldThrough(['A', 'B']);
438 - addComment('Complete the rest');
439 - expect(Scheduler).toFlushAndYield(['C']);
440 - expect(getFlameChart()).toMatchSnapshot();
441 - });
442 -
443 - it('recovers from fatal errors', () => {
444 - function Baddie() {
445 - throw new Error('Game over');
446 - }
447 -
448 - ReactNoop.render(
449 - <Parent>
450 - <Baddie />
451 - </Parent>,
452 - );
453 - try {
454 - addComment('Will fatal');
455 - expect(Scheduler).toFlushWithoutYielding();
456 - } catch (err) {
457 - expect(err.message).toBe('Game over');
458 - }
459 - ReactNoop.render(
460 - <Parent>
461 - <Child />
462 - </Parent>,
463 - );
464 - addComment('Will reconcile from a clean state');
465 - expect(Scheduler).toFlushWithoutYielding();
466 - expect(getFlameChart()).toMatchSnapshot();
467 - });
468 -
469 - it('recovers from caught errors', () => {
470 - function Baddie() {
471 - throw new Error('Game over');
472 - }
473 -
474 - function ErrorReport() {
475 - return <div />;
476 - }
477 -
478 - class Boundary extends React.Component {
479 - state = {error: null};
480 - componentDidCatch(error) {
481 - this.setState({error});
482 - }
483 - render() {
484 - if (this.state.error) {
485 - return <ErrorReport />;
486 - }
487 - return this.props.children;
488 - }
489 - }
490 -
491 - ReactNoop.render(
492 - <Parent>
493 - <Boundary>
494 - <Parent>
495 - <Baddie />
496 - </Parent>
497 - </Boundary>
498 - </Parent>,
499 - );
500 - addComment('Stop on Baddie and restart from Boundary');
501 - expect(Scheduler).toFlushWithoutYielding();
502 - expect(getFlameChart()).toMatchSnapshot();
503 - });
504 -
505 - it('deduplicates lifecycle names during commit to reduce overhead', () => {
506 - class A extends React.Component {
507 - componentDidUpdate() {}
508 - render() {
509 - return <div />;
510 - }
511 - }
512 -
513 - class B extends React.Component {
514 - componentDidUpdate(prevProps) {
515 - if (this.props.cascade && !prevProps.cascade) {
516 - this.setState({});
517 - }
518 - }
519 - render() {
520 - return <div />;
521 - }
522 - }
523 -
524 - ReactNoop.render(
525 - <Parent>
526 - <A />
527 - <B />
528 - <A />
529 - <B />
530 - </Parent>,
531 - );
532 - expect(Scheduler).toFlushWithoutYielding();
533 - resetFlamechart();
534 -
535 - ReactNoop.render(
536 - <Parent>
537 - <A />
538 - <B />
539 - <A />
540 - <B />
541 - </Parent>,
542 - );
543 - addComment('The commit phase should mention A and B just once');
544 - expect(Scheduler).toFlushWithoutYielding();
545 - ReactNoop.render(
546 - <Parent>
547 - <A />
548 - <B />
549 - <A />
550 - <B cascade={true} />
551 - </Parent>,
552 - );
553 - addComment("Because of deduplication, we don't know B was cascading,");
554 - addComment('but we should still see the warning for the commit phase.');
555 - expect(Scheduler).toFlushWithoutYielding();
556 - expect(getFlameChart()).toMatchSnapshot();
557 - });
558 -
559 - it('supports portals', () => {
560 - const portalContainer = ReactNoop.getOrCreateRootContainer(
561 - 'portalContainer',
562 - );
563 - ReactNoop.render(
564 - <Parent>
565 - {ReactNoop.createPortal(<Child />, portalContainer, null)}
566 - </Parent>,
567 - );
568 - expect(Scheduler).toFlushWithoutYielding();
569 - expect(getFlameChart()).toMatchSnapshot();
570 - });
571 -
572 - it('supports memo', () => {
573 - const MemoFoo = React.memo(function Foo() {
574 - return <div />;
575 - });
576 - ReactNoop.render(
577 - <Parent>
578 - <MemoFoo />
579 - </Parent>,
580 - );
581 - expect(Scheduler).toFlushWithoutYielding();
582 - expect(getFlameChart()).toMatchSnapshot();
583 - });
584 -
585 - it('supports Suspense and lazy', async () => {
586 - function Spinner() {
587 - return <span />;
588 - }
589 -
590 - function fakeImport(result) {
591 - return {default: result};
592 - }
593 -
594 - let resolve;
595 - const LazyFoo = React.lazy(
596 - () =>
597 - new Promise(r => {
598 - resolve = r;
599 - }),
600 - );
601 -
602 - // Initial render
603 - ReactNoop.render(
604 - <Parent>
605 - <React.Suspense fallback={<Spinner />} />
606 - </Parent>,
607 - );
608 - expect(Scheduler).toFlushWithoutYielding();
609 - expect(getFlameChart()).toMatchSnapshot();
610 -
611 - // Update that suspends
612 - ReactNoop.render(
613 - <Parent>
614 - <React.Suspense fallback={<Spinner />}>
615 - <LazyFoo />
616 - </React.Suspense>
617 - </Parent>,
618 - );
619 - expect(Scheduler).toFlushWithoutYielding();
620 - expect(getFlameChart()).toMatchSnapshot();
621 -
622 - resolve(
623 - fakeImport(function Foo() {
624 - return <div />;
625 - }),
626 - );
627 -
628 - await Promise.resolve();
629 -
630 - ReactNoop.render(
631 - <Parent>
632 - <React.Suspense>
633 - <LazyFoo />
634 - </React.Suspense>
635 - </Parent>,
636 - );
637 - expect(Scheduler).toFlushWithoutYielding();
638 - expect(getFlameChart()).toMatchSnapshot();
639 - });
640 -
641 - it('does not schedule an extra callback if setState is called during a synchronous commit phase', () => {
642 - class Component extends React.Component {
643 - state = {step: 1};
644 - componentDidMount() {
645 - this.setState({step: 2});
646 - }
647 - render() {
648 - return <span prop={this.state.step} />;
649 - }
650 - }
651 - ReactNoop.flushSync(() => {
652 - ReactNoop.render(<Component />);
653 - });
654 - expect(getFlameChart()).toMatchSnapshot();
655 - });
656 -
657 - it('warns if an in-progress update is interrupted', () => {
658 - function Foo() {
659 - Scheduler.unstable_yieldValue('Foo');
660 - return <span />;
661 - }
662 -
663 - ReactNoop.render(<Foo />);
664 - ReactNoop.flushNextYield();
665 - ReactNoop.flushSync(() => {
666 - ReactNoop.render(<Foo />);
667 - });
668 - expect(Scheduler).toHaveYielded(['Foo']);
669 - expect(Scheduler).toFlushWithoutYielding();
670 - expect(getFlameChart()).toMatchSnapshot();
671 - });
672 -
673 - it('warns if async work expires (starvation)', () => {
674 - function Foo() {
675 - return <span />;
676 - }
677 -
678 - ReactNoop.render(<Foo />);
679 - ReactNoop.expire(6000);
680 - expect(Scheduler).toFlushWithoutYielding();
681 - expect(getFlameChart()).toMatchSnapshot();
682 - });
683 -});
packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap deleted
-477
@@ -1,477 +0,0 @@
1 -// Jest Snapshot v1, https://goo.gl/fbAQLP
2 -
3 -exports[`ReactDebugFiberPerf captures all lifecycles 1`] = `
4 -"// Mount
5 -⚛ (React Tree Reconciliation: Completed Root)
6 - ⚛ AllLifecycles [mount]
7 - ⚛ AllLifecycles.componentWillMount
8 - ⚛ AllLifecycles.getChildContext
9 -
10 -⚛ (Committing Changes)
11 - ⚛ (Committing Snapshot Effects: 0 Total)
12 - ⚛ (Committing Host Effects: 1 Total)
13 - ⚛ (Calling Lifecycle Methods: 1 Total)
14 - ⚛ AllLifecycles.componentDidMount
15 -
16 -// Update
17 -⚛ (React Tree Reconciliation: Completed Root)
18 - ⚛ AllLifecycles [update]
19 - ⚛ AllLifecycles.componentWillReceiveProps
20 - ⚛ AllLifecycles.shouldComponentUpdate
21 - ⚛ AllLifecycles.componentWillUpdate
22 - ⚛ AllLifecycles.getChildContext
23 -
24 -⚛ (Committing Changes)
25 - ⚛ (Committing Snapshot Effects: 0 Total)
26 - ⚛ (Committing Host Effects: 2 Total)
27 - ⚛ (Calling Lifecycle Methods: 2 Total)
28 - ⚛ AllLifecycles.componentDidUpdate
29 -
30 -// Unmount
31 -⚛ (React Tree Reconciliation: Completed Root)
32 -
33 -⚛ (Committing Changes)
34 - ⚛ (Committing Snapshot Effects: 0 Total)
35 - ⚛ (Committing Host Effects: 1 Total)
36 - ⚛ AllLifecycles.componentWillUnmount
37 - ⚛ (Calling Lifecycle Methods: 0 Total)
38 -"
39 -`;
40 -
41 -exports[`ReactDebugFiberPerf deduplicates lifecycle names during commit to reduce overhead 1`] = `
42 -"// The commit phase should mention A and B just once
43 -⚛ (React Tree Reconciliation: Completed Root)
44 - ⚛ Parent [update]
45 - ⚛ A [update]
46 - ⚛ B [update]
47 - ⚛ A [update]
48 - ⚛ B [update]
49 -
50 -⚛ (Committing Changes)
51 - ⚛ (Committing Snapshot Effects: 0 Total)
52 - ⚛ (Committing Host Effects: 9 Total)
53 - ⚛ (Calling Lifecycle Methods: 9 Total)
54 - ⚛ A.componentDidUpdate
55 - ⚛ B.componentDidUpdate
56 -
57 -// Because of deduplication, we don't know B was cascading,
58 -// but we should still see the warning for the commit phase.
59 -⚛ (React Tree Reconciliation: Completed Root)
60 - ⚛ Parent [update]
61 - ⚛ A [update]
62 - ⚛ B [update]
63 - ⚛ A [update]
64 - ⚛ B [update]
65 -
66 -⛔ (Committing Changes) Warning: Lifecycle hook scheduled a cascading update
67 - ⚛ (Committing Snapshot Effects: 0 Total)
68 - ⚛ (Committing Host Effects: 9 Total)
69 - ⚛ (Calling Lifecycle Methods: 9 Total)
70 - ⚛ A.componentDidUpdate
71 - ⚛ B.componentDidUpdate
72 -
73 -⚛ (React Tree Reconciliation: Completed Root)
74 - ⚛ B [update]
75 -
76 -⚛ (Committing Changes)
77 - ⚛ (Committing Snapshot Effects: 0 Total)
78 - ⚛ (Committing Host Effects: 2 Total)
79 - ⚛ (Calling Lifecycle Methods: 2 Total)
80 - ⚛ B.componentDidUpdate
81 -"
82 -`;
83 -
84 -exports[`ReactDebugFiberPerf does not include StrictMode or Profiler components in measurements 1`] = `
85 -"// Mount
86 -⚛ (React Tree Reconciliation: Completed Root)
87 - ⚛ Profiler [mount]
88 - ⚛ Parent [mount]
89 - ⚛ Child [mount]
90 -
91 -⚛ (Committing Changes)
92 - ⚛ (Committing Snapshot Effects: 0 Total)
93 - ⚛ (Committing Host Effects: 1 Total)
94 - ⚛ (Calling Lifecycle Methods: 0 Total)
95 -"
96 -`;
97 -
98 -exports[`ReactDebugFiberPerf does not include context provider or consumer in measurements 1`] = `
99 -"// Mount
100 -⚛ (React Tree Reconciliation: Completed Root)
101 - ⚛ Parent [mount]
102 - ⚛ Child [mount]
103 -
104 -⚛ (Committing Changes)
105 - ⚛ (Committing Snapshot Effects: 0 Total)
106 - ⚛ (Committing Host Effects: 1 Total)
107 - ⚛ (Calling Lifecycle Methods: 0 Total)
108 -"
109 -`;
110 -
111 -exports[`ReactDebugFiberPerf does not schedule an extra callback if setState is called during a synchronous commit phase 1`] = `
112 -"⚛ (React Tree Reconciliation: Completed Root)
113 - ⚛ Component [mount]
114 -
115 -⛔ (Committing Changes) Warning: Lifecycle hook scheduled a cascading update
116 - ⚛ (Committing Snapshot Effects: 0 Total)
117 - ⚛ (Committing Host Effects: 1 Total)
118 - ⚛ (Calling Lifecycle Methods: 1 Total)
119 - ⛔ Component.componentDidMount Warning: Scheduled a cascading update
120 -
121 -⚛ (React Tree Reconciliation: Completed Root)
122 - ⚛ Component [update]
123 -
124 -⚛ (Committing Changes)
125 - ⚛ (Committing Snapshot Effects: 0 Total)
126 - ⚛ (Committing Host Effects: 1 Total)
127 - ⚛ (Calling Lifecycle Methods: 1 Total)
128 -"
129 -`;
130 -
131 -exports[`ReactDebugFiberPerf does not treat setState from cWM or cWRP as cascading 1`] = `
132 -"// Should not print a warning
133 -⚛ (React Tree Reconciliation: Completed Root)
134 - ⚛ Parent [mount]
135 - ⚛ NotCascading [mount]
136 - ⚛ NotCascading.componentWillMount
137 -
138 -⚛ (Committing Changes)
139 - ⚛ (Committing Snapshot Effects: 0 Total)
140 - ⚛ (Committing Host Effects: 1 Total)
141 - ⚛ (Calling Lifecycle Methods: 0 Total)
142 -
143 -// Should not print a warning
144 -⚛ (React Tree Reconciliation: Completed Root)
145 - ⚛ Parent [update]
146 - ⚛ NotCascading [update]
147 - ⚛ NotCascading.componentWillReceiveProps
148 -
149 -⚛ (Committing Changes)
150 - ⚛ (Committing Snapshot Effects: 0 Total)
151 - ⚛ (Committing Host Effects: 2 Total)
152 - ⚛ (Calling Lifecycle Methods: 2 Total)
153 -"
154 -`;
155 -
156 -exports[`ReactDebugFiberPerf measures a simple reconciliation 1`] = `
157 -"// Mount
158 -⚛ (React Tree Reconciliation: Completed Root)
159 - ⚛ Parent [mount]
160 - ⚛ Child [mount]
161 -
162 -⚛ (Committing Changes)
163 - ⚛ (Committing Snapshot Effects: 0 Total)
164 - ⚛ (Committing Host Effects: 1 Total)
165 - ⚛ (Calling Lifecycle Methods: 0 Total)
166 -
167 -// Update
168 -⚛ (React Tree Reconciliation: Completed Root)
169 - ⚛ Parent [update]
170 - ⚛ Child [update]
171 -
172 -⚛ (Committing Changes)
173 - ⚛ (Committing Snapshot Effects: 0 Total)
174 - ⚛ (Committing Host Effects: 2 Total)
175 - ⚛ (Calling Lifecycle Methods: 2 Total)
176 -
177 -// Unmount
178 -⚛ (React Tree Reconciliation: Completed Root)
179 -
180 -⚛ (Committing Changes)
181 - ⚛ (Committing Snapshot Effects: 0 Total)
182 - ⚛ (Committing Host Effects: 1 Total)
183 - ⚛ (Calling Lifecycle Methods: 0 Total)
184 -"
185 -`;
186 -
187 -exports[`ReactDebugFiberPerf measures deferred work in chunks 1`] = `
188 -"// Start rendering through B
189 -⚛ (React Tree Reconciliation: Yielded)
190 - ⚛ Parent [mount]
191 - ⚛ A [mount]
192 - ⚛ Child [mount]
193 - ⚛ B [mount]
194 -
195 -// Complete the rest
196 -⚛ (React Tree Reconciliation: Completed Root)
197 - ⚛ Parent [mount]
198 - ⚛ B [mount]
199 - ⚛ Child [mount]
200 - ⚛ C [mount]
201 - ⚛ Child [mount]
202 -
203 -⚛ (Committing Changes)
204 - ⚛ (Committing Snapshot Effects: 0 Total)
205 - ⚛ (Committing Host Effects: 1 Total)
206 - ⚛ (Calling Lifecycle Methods: 0 Total)
207 -"
208 -`;
209 -
210 -exports[`ReactDebugFiberPerf measures deprioritized work 1`] = `
211 -"// Flush the parent
212 -⚛ (React Tree Reconciliation: Completed Root)
213 - ⚛ Parent [mount]
214 -
215 -⚛ (Committing Changes)
216 - ⚛ (Committing Snapshot Effects: 0 Total)
217 - ⚛ (Committing Host Effects: 1 Total)
218 - ⚛ (Calling Lifecycle Methods: 0 Total)
219 -
220 -// Flush the child
221 -⚛ (React Tree Reconciliation: Completed Root)
222 - ⚛ Child [mount]
223 -
224 -⚛ (Committing Changes)
225 - ⚛ (Committing Snapshot Effects: 0 Total)
226 - ⚛ (Committing Host Effects: 1 Total)
227 - ⚛ (Calling Lifecycle Methods: 0 Total)
228 -"
229 -`;
230 -
231 -exports[`ReactDebugFiberPerf properly displays the forwardRef component in measurements 1`] = `
232 -"// Mount
233 -⚛ (React Tree Reconciliation: Completed Root)
234 - ⚛ Parent [mount]
235 - ⚛ ForwardRef [mount]
236 - ⚛ Child [mount]
237 - ⚛ ForwardRef(refForwarder) [mount]
238 - ⚛ Child [mount]
239 - ⚛ ForwardRef(OverriddenName) [mount]
240 - ⚛ Child [mount]
241 -
242 -⚛ (Committing Changes)
243 - ⚛ (Committing Snapshot Effects: 0 Total)
244 - ⚛ (Committing Host Effects: 1 Total)
245 - ⚛ (Calling Lifecycle Methods: 0 Total)
246 -"
247 -`;
248 -
249 -exports[`ReactDebugFiberPerf recovers from caught errors 1`] = `
250 -"// Stop on Baddie and restart from Boundary
251 -⚛ (React Tree Reconciliation: Completed Root)
252 - ⚛ Parent [mount]
253 - ⛔ Boundary [mount] Warning: An error was thrown inside this error boundary
254 - ⚛ Parent [mount]
255 - ⚛ Baddie [mount]
256 - ⚛ Boundary [mount]
257 -
258 -⚛ (React Tree Reconciliation: Completed Root)
259 - ⚛ Parent [mount]
260 - ⛔ Boundary [mount] Warning: An error was thrown inside this error boundary
261 - ⚛ Parent [mount]
262 - ⚛ Baddie [mount]
263 - ⚛ Boundary [mount]
264 -
265 -⛔ (Committing Changes) Warning: Lifecycle hook scheduled a cascading update
266 - ⚛ (Committing Snapshot Effects: 0 Total)
267 - ⚛ (Committing Host Effects: 2 Total)
268 - ⚛ (Calling Lifecycle Methods: 1 Total)
269 -
270 -⚛ (React Tree Reconciliation: Completed Root)
271 - ⚛ Boundary [update]
272 - ⚛ ErrorReport [mount]
273 -
274 -⚛ (Committing Changes)
275 - ⚛ (Committing Snapshot Effects: 0 Total)
276 - ⚛ (Committing Host Effects: 1 Total)
277 - ⚛ (Calling Lifecycle Methods: 0 Total)
278 -"
279 -`;
280 -
281 -exports[`ReactDebugFiberPerf recovers from fatal errors 1`] = `
282 -"// Will fatal
283 -⚛ (React Tree Reconciliation: Completed Root)
284 - ⚛ Parent [mount]
285 - ⚛ Baddie [mount]
286 -
287 -⚛ (React Tree Reconciliation: Completed Root)
288 - ⚛ Parent [mount]
289 - ⚛ Baddie [mount]
290 -
291 -⚛ (Committing Changes)
292 - ⚛ (Committing Snapshot Effects: 0 Total)
293 - ⚛ (Committing Host Effects: 1 Total)
294 - ⚛ (Calling Lifecycle Methods: 1 Total)
295 -
296 -// Will reconcile from a clean state
297 -⚛ (React Tree Reconciliation: Completed Root)
298 - ⚛ Parent [mount]
299 - ⚛ Child [mount]
300 -
301 -⚛ (Committing Changes)
302 - ⚛ (Committing Snapshot Effects: 0 Total)
303 - ⚛ (Committing Host Effects: 1 Total)
304 - ⚛ (Calling Lifecycle Methods: 0 Total)
305 -"
306 -`;
307 -
308 -exports[`ReactDebugFiberPerf skips parents during setState 1`] = `
309 -"// Should include just A and B, no Parents
310 -⚛ (React Tree Reconciliation: Completed Root)
311 - ⚛ A [update]
312 - ⚛ B [update]
313 -
314 -⚛ (Committing Changes)
315 - ⚛ (Committing Snapshot Effects: 0 Total)
316 - ⚛ (Committing Host Effects: 2 Total)
317 - ⚛ (Calling Lifecycle Methods: 2 Total)
318 -"
319 -`;
320 -
321 -exports[`ReactDebugFiberPerf supports Suspense and lazy 1`] = `
322 -"⚛ (React Tree Reconciliation: Completed Root)
323 - ⚛ Parent [mount]
324 - ⚛ Suspense [mount]
325 -
326 -⚛ (Committing Changes)
327 - ⚛ (Committing Snapshot Effects: 0 Total)
328 - ⚛ (Committing Host Effects: 1 Total)
329 - ⚛ (Calling Lifecycle Methods: 0 Total)
330 -"
331 -`;
332 -
333 -exports[`ReactDebugFiberPerf supports Suspense and lazy 2`] = `
334 -"⚛ (React Tree Reconciliation: Completed Root)
335 - ⚛ Parent [mount]
336 - ⚛ Suspense [mount]
337 -
338 -⚛ (Committing Changes)
339 - ⚛ (Committing Snapshot Effects: 0 Total)
340 - ⚛ (Committing Host Effects: 1 Total)
341 - ⚛ (Calling Lifecycle Methods: 0 Total)
342 -
343 -⚛ (React Tree Reconciliation: Completed Root)
344 - ⚛ Parent [update]
345 - ⛔ Suspense [update] Warning: Rendering was suspended
346 - ⚛ Suspense [update]
347 - ⚛ Spinner [mount]
348 -"
349 -`;
350 -
351 -exports[`ReactDebugFiberPerf supports Suspense and lazy 3`] = `
352 -"⚛ (React Tree Reconciliation: Completed Root)
353 - ⚛ Parent [mount]
354 - ⚛ Suspense [mount]
355 -
356 -⚛ (Committing Changes)
357 - ⚛ (Committing Snapshot Effects: 0 Total)
358 - ⚛ (Committing Host Effects: 1 Total)
359 - ⚛ (Calling Lifecycle Methods: 0 Total)
360 -
361 -⚛ (React Tree Reconciliation: Completed Root)
362 - ⚛ Parent [update]
363 - ⛔ Suspense [update] Warning: Rendering was suspended
364 - ⚛ Suspense [update]
365 - ⚛ Spinner [mount]
366 -
367 -⚛ (React Tree Reconciliation: Completed Root)
368 - ⚛ Parent [update]
369 - ⚛ Suspense [update]
370 - ⚛ Foo [mount]
371 -
372 -⚛ (Committing Changes)
373 - ⚛ (Committing Snapshot Effects: 0 Total)
374 - ⚛ (Committing Host Effects: 2 Total)
375 - ⚛ (Calling Lifecycle Methods: 1 Total)
376 -"
377 -`;
378 -
379 -exports[`ReactDebugFiberPerf supports memo 1`] = `
380 -"⚛ (React Tree Reconciliation: Completed Root)
381 - ⚛ Parent [mount]
382 - ⚛ Foo [mount]
383 -
384 -⚛ (Committing Changes)
385 - ⚛ (Committing Snapshot Effects: 0 Total)
386 - ⚛ (Committing Host Effects: 1 Total)
387 - ⚛ (Calling Lifecycle Methods: 0 Total)
388 -"
389 -`;
390 -
391 -exports[`ReactDebugFiberPerf supports portals 1`] = `
392 -"⚛ (React Tree Reconciliation: Completed Root)
393 - ⚛ Parent [mount]
394 - ⚛ Child [mount]
395 -
396 -⚛ (Committing Changes)
397 - ⚛ (Committing Snapshot Effects: 0 Total)
398 - ⚛ (Committing Host Effects: 2 Total)
399 - ⚛ (Calling Lifecycle Methods: 0 Total)
400 -"
401 -`;
402 -
403 -exports[`ReactDebugFiberPerf warns if an in-progress update is interrupted 1`] = `
404 -"⚛ (React Tree Reconciliation: Yielded)
405 - ⚛ Foo [mount]
406 -
407 -⛔ (React Tree Reconciliation: Completed Root) Warning: A top-level update interrupted the previous render
408 - ⚛ Foo [mount]
409 -
410 -⚛ (Committing Changes)
411 - ⚛ (Committing Snapshot Effects: 0 Total)
412 - ⚛ (Committing Host Effects: 1 Total)
413 - ⚛ (Calling Lifecycle Methods: 0 Total)
414 -
415 -⚛ (React Tree Reconciliation: Completed Root)
416 -
417 -⚛ (Committing Changes)
418 - ⚛ (Committing Snapshot Effects: 0 Total)
419 - ⚛ (Committing Host Effects: 0 Total)
420 - ⚛ (Calling Lifecycle Methods: 0 Total)
421 -"
422 -`;
423 -
424 -exports[`ReactDebugFiberPerf warns if async work expires (starvation) 1`] = `
425 -"⚛ (React Tree Reconciliation: Completed Root)
426 - ⚛ Foo [mount]
427 -
428 -⚛ (Committing Changes)
429 - ⚛ (Committing Snapshot Effects: 0 Total)
430 - ⚛ (Committing Host Effects: 1 Total)
431 - ⚛ (Calling Lifecycle Methods: 0 Total)
432 -"
433 -`;
434 -
435 -exports[`ReactDebugFiberPerf warns on cascading renders from setState 1`] = `
436 -"// Should print a warning
437 -⚛ (React Tree Reconciliation: Completed Root)
438 - ⚛ Parent [mount]
439 - ⚛ Cascading [mount]
440 -
441 -⛔ (Committing Changes) Warning: Lifecycle hook scheduled a cascading update
442 - ⚛ (Committing Snapshot Effects: 0 Total)
443 - ⚛ (Committing Host Effects: 2 Total)
444 - ⚛ (Calling Lifecycle Methods: 1 Total)
445 - ⛔ Cascading.componentDidMount Warning: Scheduled a cascading update
446 -
447 -⚛ (React Tree Reconciliation: Completed Root)
448 - ⚛ Cascading [update]
449 -
450 -⚛ (Committing Changes)
451 - ⚛ (Committing Snapshot Effects: 0 Total)
452 - ⚛ (Committing Host Effects: 1 Total)
453 - ⚛ (Calling Lifecycle Methods: 1 Total)
454 -"
455 -`;
456 -
457 -exports[`ReactDebugFiberPerf warns on cascading renders from top-level render 1`] = `
458 -"// Rendering the first root
459 -⚛ (React Tree Reconciliation: Completed Root)
460 - ⚛ Cascading [mount]
461 -
462 -⛔ (Committing Changes) Warning: Lifecycle hook scheduled a cascading update
463 - ⚛ (Committing Snapshot Effects: 0 Total)
464 - ⚛ (Committing Host Effects: 1 Total)
465 - ⚛ (Calling Lifecycle Methods: 1 Total)
466 - ⛔ Cascading.componentDidMount Warning: Scheduled a cascading update
467 -
468 -// Scheduling another root from componentDidMount
469 -⚛ (React Tree Reconciliation: Completed Root)
470 - ⚛ Child [mount]
471 -
472 -⚛ (Committing Changes)
473 - ⚛ (Committing Snapshot Effects: 0 Total)
474 - ⚛ (Committing Host Effects: 1 Total)
475 - ⚛ (Calling Lifecycle Methods: 0 Total)
476 -"
477 -`;
packages/shared/ReactFeatureFlags.js
-7
@@ -7,8 +7,6 @@
7 * @flow strict
8 */
9
10 -export const enableUserTimingAPI = __DEV__;
11 -
10 // Helps identify side effects in render-phase lifecycle hooks and setState
11 // reducers by double invoking them in Strict Mode.
12 export const debugRenderPhaseSideEffectsForStrictMode = __DEV__;
@@ -39,11 +37,6 @@ export const enableBlocksAPI = __EXPERIMENTAL__;
37 // Only used in www builds.
38 export const enableSchedulerDebugging = false;
39
42 -// Only used in www builds.
43 -export function addUserTimingListener() {
44 - throw new Error('Not implemented.');
45 -}
46 -
40 // Disable javascript: URL strings in href for XSS protection.
41 export const disableJavaScriptURLs = false;
42
packages/shared/forks/ReactFeatureFlags.native-fb.js
-8
@@ -7,13 +7,10 @@
7 * @flow
8 */
9
10 -import invariant from 'shared/invariant';
11 -
10 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11 import typeof * as ExportsType from './ReactFeatureFlags.native-fb';
12
13 // The rest of the flags are static for better dead code elimination.
16 -export const enableUserTimingAPI = __DEV__;
14 export const enableProfilerTimer = __PROFILE__;
15 export const enableProfilerCommitHooks = false;
16 export const enableSchedulerTracing = __PROFILE__;
@@ -54,11 +51,6 @@ export const throwEarlyForMysteriousError = true;
51
52 export const enableNewReconciler = false;
53
57 -// Only used in www builds.
58 -export function addUserTimingListener() {
59 - invariant(false, 'Not implemented.');
60 -}
61 -
54 // Flow magic to verify the exports of this file match the original version.
55 // eslint-disable-next-line no-unused-vars
56 type Check<_X, Y: _X, X: Y = _X> = null;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-8
@@ -7,13 +7,10 @@
7 * @flow
8 */
9
10 -import invariant from 'shared/invariant';
11 -
10 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11 import typeof * as ExportsType from './ReactFeatureFlags.native-oss';
12
13 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 -export const enableUserTimingAPI = __DEV__;
14 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
15 export const warnAboutDeprecatedLifecycles = true;
16 export const enableProfilerTimer = __PROFILE__;
@@ -53,11 +50,6 @@ export const throwEarlyForMysteriousError = false;
50
51 export const enableNewReconciler = false;
52
56 -// Only used in www builds.
57 -export function addUserTimingListener() {
58 - invariant(false, 'Not implemented.');
59 -}
60 -
53 // Flow magic to verify the exports of this file match the original version.
54 // eslint-disable-next-line no-unused-vars
55 type Check<_X, Y: _X, X: Y = _X> = null;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-8
@@ -7,13 +7,10 @@
7 * @flow
8 */
9
10 -import invariant from 'shared/invariant';
11 -
10 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11 import typeof * as ExportsType from './ReactFeatureFlags.test-renderer';
12
13 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 -export const enableUserTimingAPI = __DEV__;
14 export const warnAboutDeprecatedLifecycles = true;
15 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
16 export const enableProfilerTimer = __PROFILE__;
@@ -53,11 +50,6 @@ export const throwEarlyForMysteriousError = false;
50
51 export const enableNewReconciler = false;
52
56 -// Only used in www builds.
57 -export function addUserTimingListener() {
58 - invariant(false, 'Not implemented.');
59 -}
60 -
53 // Flow magic to verify the exports of this file match the original version.
54 // eslint-disable-next-line no-unused-vars
55 type Check<_X, Y: _X, X: Y = _X> = null;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-8
@@ -7,13 +7,10 @@
7 * @flow
8 */
9
10 -import invariant from 'shared/invariant';
11 -
10 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11 import typeof * as ExportsType from './ReactFeatureFlags.test-renderer.www';
12
13 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 -export const enableUserTimingAPI = __DEV__;
14 export const warnAboutDeprecatedLifecycles = true;
15 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
16 export const enableProfilerTimer = __PROFILE__;
@@ -53,11 +50,6 @@ export const throwEarlyForMysteriousError = false;
50
51 export const enableNewReconciler = false;
52
56 -// Only used in www builds.
57 -export function addUserTimingListener() {
58 - invariant(false, 'Not implemented.');
59 -}
60 -
53 // Flow magic to verify the exports of this file match the original version.
54 // eslint-disable-next-line no-unused-vars
55 type Check<_X, Y: _X, X: Y = _X> = null;
packages/shared/forks/ReactFeatureFlags.testing.js
-8
@@ -7,13 +7,10 @@
7 * @flow
8 */
9
10 -import invariant from 'shared/invariant';
11 -
10 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11 import typeof * as ExportsType from './ReactFeatureFlags.testing';
12
13 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 -export const enableUserTimingAPI = __DEV__;
14 export const warnAboutDeprecatedLifecycles = true;
15 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
16 export const enableProfilerTimer = __PROFILE__;
@@ -53,11 +50,6 @@ export const throwEarlyForMysteriousError = false;
50
51 export const enableNewReconciler = false;
52
56 -// Only used in www builds.
57 -export function addUserTimingListener() {
58 - invariant(false, 'Not implemented.');
59 -}
60 -
53 // Flow magic to verify the exports of this file match the original version.
54 // eslint-disable-next-line no-unused-vars
55 type Check<_X, Y: _X, X: Y = _X> = null;
packages/shared/forks/ReactFeatureFlags.testing.www.js
-8
@@ -7,13 +7,10 @@
7 * @flow
8 */
9
10 -import invariant from 'shared/invariant';
11 -
10 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11 import typeof * as ExportsType from './ReactFeatureFlags.testing.www';
12
13 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 -export const enableUserTimingAPI = false;
14 export const warnAboutDeprecatedLifecycles = true;
15 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
16 export const enableProfilerTimer = false;
@@ -53,11 +50,6 @@ export const throwEarlyForMysteriousError = false;
50
51 export const enableNewReconciler = false;
52
56 -// Only used in www builds.
57 -export function addUserTimingListener() {
58 - invariant(false, 'Not implemented.');
59 -}
60 -
53 // Flow magic to verify the exports of this file match the original version.
54 // eslint-disable-next-line no-unused-vars
55 type Check<_X, Y: _X, X: Y = _X> = null;
packages/shared/forks/ReactFeatureFlags.www.js
-35
@@ -30,14 +30,6 @@ export const {
30 // On WWW, __EXPERIMENTAL__ is used for a new modern build.
31 // It's not used anywhere in production yet.
32
33 -// In www, we have experimental support for gathering data
34 -// from User Timing API calls in production. By default, we
35 -// only emit performance.mark/measure calls in __DEV__. But if
36 -// somebody calls addUserTimingListener() which is exposed as an
37 -// experimental FB-only export, we call performance.mark/measure
38 -// as long as there is more than a single listener.
39 -export let enableUserTimingAPI = __DEV__ && !__EXPERIMENTAL__;
40 -
33 export const enableProfilerTimer = __PROFILE__;
34 export const enableProfilerCommitHooks = __PROFILE__;
35
@@ -59,33 +51,6 @@ export const enableBlocksAPI = true;
51
52 export const disableJavaScriptURLs = true;
53
62 -let refCount = 0;
63 -export function addUserTimingListener() {
64 - if (__DEV__) {
65 - // Noop.
66 - return () => {};
67 - }
68 - refCount++;
69 - updateFlagOutsideOfReactCallStack();
70 - return () => {
71 - refCount--;
72 - updateFlagOutsideOfReactCallStack();
73 - };
74 -}
75 -
76 -// The flag is intentionally updated in a timeout.
77 -// We don't support toggling it during reconciliation or
78 -// commit since that would cause mismatching user timing API calls.
79 -let timeout = null;
80 -function updateFlagOutsideOfReactCallStack() {
81 - if (!timeout) {
82 - timeout = setTimeout(() => {
83 - timeout = null;
84 - enableUserTimingAPI = refCount > 0;
85 - });
86 - }
87 -}
88 -
54 export const enableDeprecatedFlareAPI = true;
55
56 export const enableFundamentalAPI = false;
scripts/jest/setupTests.www.js
-1
@@ -15,7 +15,6 @@ jest.mock('shared/ReactFeatureFlags', () => {
15 // configuration, too. Then remove these overrides.
16 wwwFlags.disableLegacyContext = defaultFlags.disableLegacyContext;
17 wwwFlags.warnAboutUnmockedScheduler = defaultFlags.warnAboutUnmockedScheduler;
18 - wwwFlags.enableUserTimingAPI = defaultFlags.enableUserTimingAPI;
18 wwwFlags.disableJavaScriptURLs = defaultFlags.disableJavaScriptURLs;
19 wwwFlags.enableDeprecatedFlareAPI = defaultFlags.enableDeprecatedFlareAPI;
20 wwwFlags.disableModulePatternComponents =