Skip to content

Commit

Permalink
Experiment with using an object literal for Fiber creation
Browse files Browse the repository at this point in the history
Object literals should be faster at least on React Native with Hermes as the JS engine.
It might also be interesting to confirm the old comments in this file from years ago are even still valid. Creating an object from a literal should be a simpler operation.

It's a bit unfortunate that this introduces a bunch of copied code, but since we rearely update the fields on fibers, this seems like an okay tradeoff for a hot code path. An alternative would be some sort of macro system, but that doesn't seem worth the extra complexity.
  • Loading branch information
kassens committed Apr 3, 2024
1 parent 20e710a commit 6aee07c
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 7 deletions.
81 changes: 74 additions & 7 deletions packages/react-reconciler/src/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand All @@ -232,6 +233,72 @@ function createFiber(
return new FiberNode(tag, pendingProps, key, mode);
}

function createFiberImplObject(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
): Fiber {
const fiber: 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,
};

if (enableProfilerTimer) {
fiber.actualDuration = 0;
fiber.actualStartTime = -1;
fiber.selfBaseDuration = 0;
fiber.treeBaseDuration = 0;
}

if (__DEV__) {
fiber._debugInfo = null;
fiber._debugOwner = null;
fiber._debugNeedsRemount = false;
fiber._debugHookTypes = null;

if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
Object.preventExtensions(fiber);
}
}
return fiber;
}

const createFiber = enableObjectFiber
? createFiberImplObject
: createFiberImplClass;

function shouldConstruct(Component: Function) {
const prototype = Component.prototype;
return !!(prototype && prototype.isReactComponent);
Expand Down
5 changes: 5 additions & 0 deletions packages/shared/ReactFeatureFlags.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export const enableRenderableContext = __VARIANT__;
export const enableUnifiedSyncLane = __VARIANT__;
export const passChildrenWhenCloningPersistedNodes = __VARIANT__;
export const useModernStrictMode = __VARIANT__;
export const enableObjectFiber = __VARIANT__;
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.native-fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const {
enableComponentStackLocations,
enableDeferRootSchedulingToMicrotask,
enableInfiniteRenderLoopDetection,
enableObjectFiber,
enableRenderableContext,
enableUnifiedSyncLane,
passChildrenWhenCloningPersistedNodes,
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.native-oss.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.test-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Original file line number Diff line number Diff line change
Expand Up @@ -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);
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.www.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

0 comments on commit 6aee07c

Please sign in to comment.