mirror of
https://github.com/facebook/react.git
synced 2026-02-25 13:13:03 +00:00
We've heard from multiple contributors that the Reconciler forking mechanism was confusing and/or annoying to deal with. Since it's currently unused and there's no immediate plans to start using it again, this removes the forking. Fully removing the fork is split into 2 steps to preserve file history: **#25774 previous PR that did the bulk of the work:** - remove `enableNewReconciler` feature flag. - remove `unstable_isNewReconciler` export - remove eslint rules for cross fork imports - remove `*.new.js` files and update imports - merge non-suffixed files into `*.old` files where both exist (sometimes types were defined there) **This PR** - rename `*.old` files
241 lines
6.4 KiB
JavaScript
241 lines
6.4 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
*/
|
|
|
|
import type {Fiber} from './ReactInternalTypes';
|
|
|
|
import {
|
|
enableProfilerCommitHooks,
|
|
enableProfilerNestedUpdatePhase,
|
|
enableProfilerTimer,
|
|
} from 'shared/ReactFeatureFlags';
|
|
import {HostRoot, Profiler} from './ReactWorkTags';
|
|
|
|
// Intentionally not named imports because Rollup would use dynamic dispatch for
|
|
// CommonJS interop named imports.
|
|
import * as Scheduler from 'scheduler';
|
|
|
|
const {unstable_now: now} = Scheduler;
|
|
|
|
export type ProfilerTimer = {
|
|
getCommitTime(): number,
|
|
isCurrentUpdateNested(): boolean,
|
|
markNestedUpdateScheduled(): void,
|
|
recordCommitTime(): void,
|
|
startProfilerTimer(fiber: Fiber): void,
|
|
stopProfilerTimerIfRunning(fiber: Fiber): void,
|
|
stopProfilerTimerIfRunningAndRecordDelta(fiber: Fiber): void,
|
|
syncNestedUpdateFlag(): void,
|
|
...
|
|
};
|
|
|
|
let commitTime: number = 0;
|
|
let layoutEffectStartTime: number = -1;
|
|
let profilerStartTime: number = -1;
|
|
let passiveEffectStartTime: number = -1;
|
|
|
|
/**
|
|
* Tracks whether the current update was a nested/cascading update (scheduled from a layout effect).
|
|
*
|
|
* The overall sequence is:
|
|
* 1. render
|
|
* 2. commit (and call `onRender`, `onCommit`)
|
|
* 3. check for nested updates
|
|
* 4. flush passive effects (and call `onPostCommit`)
|
|
*
|
|
* Nested updates are identified in step 3 above,
|
|
* but step 4 still applies to the work that was just committed.
|
|
* We use two flags to track nested updates then:
|
|
* one tracks whether the upcoming update is a nested update,
|
|
* and the other tracks whether the current update was a nested update.
|
|
* The first value gets synced to the second at the start of the render phase.
|
|
*/
|
|
let currentUpdateIsNested: boolean = false;
|
|
let nestedUpdateScheduled: boolean = false;
|
|
|
|
function isCurrentUpdateNested(): boolean {
|
|
return currentUpdateIsNested;
|
|
}
|
|
|
|
function markNestedUpdateScheduled(): void {
|
|
if (enableProfilerNestedUpdatePhase) {
|
|
nestedUpdateScheduled = true;
|
|
}
|
|
}
|
|
|
|
function resetNestedUpdateFlag(): void {
|
|
if (enableProfilerNestedUpdatePhase) {
|
|
currentUpdateIsNested = false;
|
|
nestedUpdateScheduled = false;
|
|
}
|
|
}
|
|
|
|
function syncNestedUpdateFlag(): void {
|
|
if (enableProfilerNestedUpdatePhase) {
|
|
currentUpdateIsNested = nestedUpdateScheduled;
|
|
nestedUpdateScheduled = false;
|
|
}
|
|
}
|
|
|
|
function getCommitTime(): number {
|
|
return commitTime;
|
|
}
|
|
|
|
function recordCommitTime(): void {
|
|
if (!enableProfilerTimer) {
|
|
return;
|
|
}
|
|
commitTime = now();
|
|
}
|
|
|
|
function startProfilerTimer(fiber: Fiber): void {
|
|
if (!enableProfilerTimer) {
|
|
return;
|
|
}
|
|
|
|
profilerStartTime = now();
|
|
|
|
if (((fiber.actualStartTime: any): number) < 0) {
|
|
fiber.actualStartTime = now();
|
|
}
|
|
}
|
|
|
|
function stopProfilerTimerIfRunning(fiber: Fiber): void {
|
|
if (!enableProfilerTimer) {
|
|
return;
|
|
}
|
|
profilerStartTime = -1;
|
|
}
|
|
|
|
function stopProfilerTimerIfRunningAndRecordDelta(
|
|
fiber: Fiber,
|
|
overrideBaseTime: boolean,
|
|
): void {
|
|
if (!enableProfilerTimer) {
|
|
return;
|
|
}
|
|
|
|
if (profilerStartTime >= 0) {
|
|
const elapsedTime = now() - profilerStartTime;
|
|
// $FlowFixMe[unsafe-addition] addition with possible null/undefined value
|
|
fiber.actualDuration += elapsedTime;
|
|
if (overrideBaseTime) {
|
|
fiber.selfBaseDuration = elapsedTime;
|
|
}
|
|
profilerStartTime = -1;
|
|
}
|
|
}
|
|
|
|
function recordLayoutEffectDuration(fiber: Fiber): void {
|
|
if (!enableProfilerTimer || !enableProfilerCommitHooks) {
|
|
return;
|
|
}
|
|
|
|
if (layoutEffectStartTime >= 0) {
|
|
const elapsedTime = now() - layoutEffectStartTime;
|
|
|
|
layoutEffectStartTime = -1;
|
|
|
|
// Store duration on the next nearest Profiler ancestor
|
|
// Or the root (for the DevTools Profiler to read)
|
|
let parentFiber = fiber.return;
|
|
while (parentFiber !== null) {
|
|
switch (parentFiber.tag) {
|
|
case HostRoot:
|
|
const root = parentFiber.stateNode;
|
|
root.effectDuration += elapsedTime;
|
|
return;
|
|
case Profiler:
|
|
const parentStateNode = parentFiber.stateNode;
|
|
parentStateNode.effectDuration += elapsedTime;
|
|
return;
|
|
}
|
|
parentFiber = parentFiber.return;
|
|
}
|
|
}
|
|
}
|
|
|
|
function recordPassiveEffectDuration(fiber: Fiber): void {
|
|
if (!enableProfilerTimer || !enableProfilerCommitHooks) {
|
|
return;
|
|
}
|
|
|
|
if (passiveEffectStartTime >= 0) {
|
|
const elapsedTime = now() - passiveEffectStartTime;
|
|
|
|
passiveEffectStartTime = -1;
|
|
|
|
// Store duration on the next nearest Profiler ancestor
|
|
// Or the root (for the DevTools Profiler to read)
|
|
let parentFiber = fiber.return;
|
|
while (parentFiber !== null) {
|
|
switch (parentFiber.tag) {
|
|
case HostRoot:
|
|
const root = parentFiber.stateNode;
|
|
if (root !== null) {
|
|
root.passiveEffectDuration += elapsedTime;
|
|
}
|
|
return;
|
|
case Profiler:
|
|
const parentStateNode = parentFiber.stateNode;
|
|
if (parentStateNode !== null) {
|
|
// Detached fibers have their state node cleared out.
|
|
// In this case, the return pointer is also cleared out,
|
|
// so we won't be able to report the time spent in this Profiler's subtree.
|
|
parentStateNode.passiveEffectDuration += elapsedTime;
|
|
}
|
|
return;
|
|
}
|
|
parentFiber = parentFiber.return;
|
|
}
|
|
}
|
|
}
|
|
|
|
function startLayoutEffectTimer(): void {
|
|
if (!enableProfilerTimer || !enableProfilerCommitHooks) {
|
|
return;
|
|
}
|
|
layoutEffectStartTime = now();
|
|
}
|
|
|
|
function startPassiveEffectTimer(): void {
|
|
if (!enableProfilerTimer || !enableProfilerCommitHooks) {
|
|
return;
|
|
}
|
|
passiveEffectStartTime = now();
|
|
}
|
|
|
|
function transferActualDuration(fiber: Fiber): void {
|
|
// Transfer time spent rendering these children so we don't lose it
|
|
// after we rerender. This is used as a helper in special cases
|
|
// where we should count the work of multiple passes.
|
|
let child = fiber.child;
|
|
while (child) {
|
|
// $FlowFixMe[unsafe-addition] addition with possible null/undefined value
|
|
fiber.actualDuration += child.actualDuration;
|
|
child = child.sibling;
|
|
}
|
|
}
|
|
|
|
export {
|
|
getCommitTime,
|
|
isCurrentUpdateNested,
|
|
markNestedUpdateScheduled,
|
|
recordCommitTime,
|
|
recordLayoutEffectDuration,
|
|
recordPassiveEffectDuration,
|
|
resetNestedUpdateFlag,
|
|
startLayoutEffectTimer,
|
|
startPassiveEffectTimer,
|
|
startProfilerTimer,
|
|
stopProfilerTimerIfRunning,
|
|
stopProfilerTimerIfRunningAndRecordDelta,
|
|
syncNestedUpdateFlag,
|
|
transferActualDuration,
|
|
};
|