diff --git a/packages/react-reconciler/src/ReactFiber.js b/packages/react-reconciler/src/ReactFiber.js index 7b1a6514ebd5f..3a15615e9b790 100644 --- a/packages/react-reconciler/src/ReactFiber.js +++ b/packages/react-reconciler/src/ReactFiber.js @@ -28,16 +28,17 @@ import { isHostSingletonType, } from './ReactFiberConfig'; import { - enableProfilerTimer, - enableScopeAPI, - enableLegacyHidden, - forceConcurrentByDefaultForTesting, allowConcurrentByDefault, - enableTransitionTracing, + disableLegacyMode, enableDebugTracing, enableDO_NOT_USE_disableStrictPassiveEffect, + enableLegacyHidden, + enableObjectFiber, + enableProfilerTimer, enableRenderableContext, - disableLegacyMode, + enableScopeAPI, + enableTransitionTracing, + forceConcurrentByDefaultForTesting, } from 'shared/ReactFeatureFlags'; import {NoFlags, Placement, StaticMask} from './ReactFiberFlags'; import {ConcurrentRoot} from './ReactRootTags'; @@ -222,7 +223,7 @@ function FiberNode( // is faster. // 5) It should be easy to port this to a C struct and keep a C implementation // compatible. -function createFiber( +function createFiberImplClass( tag: WorkTag, pendingProps: mixed, key: null | string, @@ -232,6 +233,217 @@ function createFiber( return new FiberNode(tag, pendingProps, key, mode); } +function createFiberImplObjectDev( + tag: WorkTag, + pendingProps: mixed, + key: null | string, + mode: TypeOfMode, +): Fiber { + const fiber = { + // Instance + tag, + key, + elementType: null, + type: null, + stateNode: null, + + // Fiber + return: null, + child: null, + sibling: null, + index: 0, + + ref: null, + refCleanup: null, + + pendingProps, + memoizedProps: null, + updateQueue: null, + memoizedState: null, + dependencies: null, + + mode, + + // Effects + flags: NoFlags, + subtreeFlags: NoFlags, + deletions: null, + + lanes: NoLanes, + childLanes: NoLanes, + + alternate: null, + + // __DEV__ only + _debugInfo: null, + _debugOwner: null, + _debugNeedsRemount: false, + _debugHookTypes: null, + }; + if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') { + Object.preventExtensions(fiber); + } + return fiber; +} +function createFiberImplObjectDevProfile( + tag: WorkTag, + pendingProps: mixed, + key: null | string, + mode: TypeOfMode, +): Fiber { + const fiber = { + // Instance + tag, + key, + elementType: null, + type: null, + stateNode: null, + + // Fiber + return: null, + child: null, + sibling: null, + index: 0, + + ref: null, + refCleanup: null, + + pendingProps, + memoizedProps: null, + updateQueue: null, + memoizedState: null, + dependencies: null, + + mode, + + // Effects + flags: NoFlags, + subtreeFlags: NoFlags, + deletions: null, + + lanes: NoLanes, + childLanes: NoLanes, + + alternate: null, + + // enableProfilerTimer only + actualDuration: 0, + actualStartTime: -1, + selfBaseDuration: 0, + treeBaseDuration: 0, + + // __DEV__ only + _debugInfo: null, + _debugOwner: null, + _debugNeedsRemount: false, + _debugHookTypes: null, + }; + if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') { + Object.preventExtensions(fiber); + } + return fiber; +} +function createFiberImplObjectProd( + tag: WorkTag, + pendingProps: mixed, + key: null | string, + mode: TypeOfMode, +): Fiber { + return { + // Instance + tag, + key, + elementType: null, + type: null, + stateNode: null, + + // Fiber + return: null, + child: null, + sibling: null, + index: 0, + + ref: null, + refCleanup: null, + + pendingProps, + memoizedProps: null, + updateQueue: null, + memoizedState: null, + dependencies: null, + + mode, + + // Effects + flags: NoFlags, + subtreeFlags: NoFlags, + deletions: null, + + lanes: NoLanes, + childLanes: NoLanes, + + alternate: null, + }; +} +function createFiberImplObjectProdProfile( + tag: WorkTag, + pendingProps: mixed, + key: null | string, + mode: TypeOfMode, +): Fiber { + return { + // Instance + tag, + key, + elementType: null, + type: null, + stateNode: null, + + // Fiber + return: null, + child: null, + sibling: null, + index: 0, + + ref: null, + refCleanup: null, + + pendingProps, + memoizedProps: null, + updateQueue: null, + memoizedState: null, + dependencies: null, + + mode, + + // Effects + flags: NoFlags, + subtreeFlags: NoFlags, + deletions: null, + + lanes: NoLanes, + childLanes: NoLanes, + + alternate: null, + + // enableProfilerTimer only + actualDuration: 0, + actualStartTime: -1, + selfBaseDuration: 0, + treeBaseDuration: 0, + }; +} + +const createFiber = !enableObjectFiber + ? createFiberImplClass + : __DEV__ + ? enableProfilerTimer + ? createFiberImplObjectDevProfile + : createFiberImplObjectDev + : enableProfilerTimer + ? createFiberImplObjectProdProfile + : createFiberImplObjectProd; + function shouldConstruct(Component: Function) { const prototype = Component.prototype; return !!(prototype && prototype.isReactComponent); diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index c527d069dcaa5..eee80fb5f48bd 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -83,6 +83,11 @@ export const enableTaint = __EXPERIMENTAL__; export const enablePostpone = __EXPERIMENTAL__; +/** + * Switches Fiber creation to a simple object instead of a constructor. + */ +export const enableObjectFiber = false; + export const enableTransitionTracing = false; // No known bugs, but needs performance testing diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js index 50c65b0038e16..77b2cc33ebe55 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js @@ -27,3 +27,4 @@ export const enableRenderableContext = __VARIANT__; export const enableUnifiedSyncLane = __VARIANT__; export const passChildrenWhenCloningPersistedNodes = __VARIANT__; export const useModernStrictMode = __VARIANT__; +export const enableObjectFiber = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 004c76d747569..9103e192d3aa1 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -25,6 +25,7 @@ export const { enableComponentStackLocations, enableDeferRootSchedulingToMicrotask, enableInfiniteRenderLoopDetection, + enableObjectFiber, enableRenderableContext, enableUnifiedSyncLane, passChildrenWhenCloningPersistedNodes, diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 79f77bdc052ca..e72c76fe5e048 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -72,6 +72,7 @@ export const enableSchedulingProfiler = __PROFILE__; export const enableLegacyCache = false; export const enableFetchInstrumentation = false; export const enablePostpone = false; +export const enableObjectFiber = false; export const disableCommentsAsDOMContainers = true; export const disableInputAttributeSyncing = false; export const disableIEWorkarounds = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index cef2b788b73ce..f3e6eaa1721c9 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -90,6 +90,7 @@ export const disableLegacyContext = true; export const disableDOMTestUtils = true; export const enableRenderableContext = true; export const enableReactTestRendererWarning = true; +export const enableObjectFiber = false; // Flow magic to verify the exports of this file match the original version. ((((null: any): ExportsType): FeatureFlagsType): ExportsType); diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 3bfc66a0069ba..c73f90a8fb3f1 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -84,6 +84,7 @@ export const disableStringRefs = false; export const enableReactTestRendererWarning = false; export const disableLegacyMode = false; export const disableDOMTestUtils = false; +export const enableObjectFiber = false; // Flow magic to verify the exports of this file match the original version. ((((null: any): ExportsType): FeatureFlagsType): ExportsType); diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 3057542f39740..60916213a9e9b 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -114,6 +114,7 @@ export const disableStringRefs = false; export const disableLegacyMode = __EXPERIMENTAL__; export const disableDOMTestUtils = false; +export const enableObjectFiber = false; // Flow magic to verify the exports of this file match the original version. ((((null: any): ExportsType): FeatureFlagsType): ExportsType);