mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
Introduce a faster version of the addProperties function (#28969)
## Summary This PR introduces a faster version of the `addProperties` function. This new function is basically the `diffProperties` with `prevProps` set to `null`, propagated constants, and all the unreachable code paths collapsed. ## How did you test this change? I've tested this change with [the benchmark app](https://github.com/react-native-community/RNNewArchitectureApp/tree/new-architecture-benchmarks) and got ~4.4% improvement in the view creation time.
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
import isArray from 'shared/isArray';
|
||||
|
||||
import {enableEarlyReturnForPropDiffing} from 'shared/ReactFeatureFlags';
|
||||
import {enableAddPropertiesFastPath} from 'shared/ReactFeatureFlags';
|
||||
|
||||
import type {AttributeConfiguration} from './ReactNativeTypes';
|
||||
|
||||
@@ -444,6 +445,68 @@ function diffProperties(
|
||||
return updatePayload;
|
||||
}
|
||||
|
||||
function fastAddProperties(
|
||||
updatePayload: null | Object,
|
||||
nextProps: Object,
|
||||
validAttributes: AttributeConfiguration,
|
||||
): null | Object {
|
||||
let attributeConfig;
|
||||
let nextProp;
|
||||
|
||||
for (const propKey in nextProps) {
|
||||
nextProp = nextProps[propKey];
|
||||
|
||||
if (nextProp === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
attributeConfig = validAttributes[propKey];
|
||||
|
||||
if (attributeConfig === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof nextProp === 'function') {
|
||||
nextProp = (true: any);
|
||||
}
|
||||
|
||||
if (typeof attributeConfig !== 'object') {
|
||||
if (!updatePayload) {
|
||||
updatePayload = ({}: {[string]: $FlowFixMe});
|
||||
}
|
||||
updatePayload[propKey] = nextProp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof attributeConfig.process === 'function') {
|
||||
if (!updatePayload) {
|
||||
updatePayload = ({}: {[string]: $FlowFixMe});
|
||||
}
|
||||
updatePayload[propKey] = attributeConfig.process(nextProp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isArray(nextProp)) {
|
||||
for (let i = 0; i < nextProp.length; i++) {
|
||||
updatePayload = fastAddProperties(
|
||||
updatePayload,
|
||||
nextProp[i],
|
||||
((attributeConfig: any): AttributeConfiguration),
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
updatePayload = fastAddProperties(
|
||||
updatePayload,
|
||||
nextProp,
|
||||
((attributeConfig: any): AttributeConfiguration),
|
||||
);
|
||||
}
|
||||
|
||||
return updatePayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* addProperties adds all the valid props to the payload after being processed.
|
||||
*/
|
||||
@@ -452,8 +515,11 @@ function addProperties(
|
||||
props: Object,
|
||||
validAttributes: AttributeConfiguration,
|
||||
): null | Object {
|
||||
// TODO: Fast path
|
||||
return diffProperties(updatePayload, emptyObject, props, validAttributes);
|
||||
if (enableAddPropertiesFastPath) {
|
||||
return fastAddProperties(updatePayload, props, validAttributes);
|
||||
} else {
|
||||
return diffProperties(updatePayload, emptyObject, props, validAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -123,6 +123,8 @@ export const enableServerComponentLogs = __EXPERIMENTAL__;
|
||||
|
||||
export const enableEarlyReturnForPropDiffing = false;
|
||||
|
||||
export const enableAddPropertiesFastPath = false;
|
||||
|
||||
/**
|
||||
* Enables an expiration time for retry lanes to avoid starvation.
|
||||
*/
|
||||
|
||||
@@ -29,3 +29,4 @@ export const enableUnifiedSyncLane = __VARIANT__;
|
||||
export const passChildrenWhenCloningPersistedNodes = __VARIANT__;
|
||||
export const useModernStrictMode = __VARIANT__;
|
||||
export const disableDefaultPropsExceptForClasses = __VARIANT__;
|
||||
export const enableAddPropertiesFastPath = __VARIANT__;
|
||||
|
||||
@@ -31,6 +31,7 @@ export const {
|
||||
passChildrenWhenCloningPersistedNodes,
|
||||
useModernStrictMode,
|
||||
disableDefaultPropsExceptForClasses,
|
||||
enableAddPropertiesFastPath,
|
||||
} = dynamicFlags;
|
||||
|
||||
// The rest of the flags are static for better dead code elimination.
|
||||
|
||||
@@ -103,6 +103,7 @@ export const enableDO_NOT_USE_disableStrictPassiveEffect = false;
|
||||
export const passChildrenWhenCloningPersistedNodes = false;
|
||||
export const enableEarlyReturnForPropDiffing = false;
|
||||
export const enableAsyncIterableChildren = false;
|
||||
export const enableAddPropertiesFastPath = false;
|
||||
|
||||
export const renameElementSymbol = true;
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ export const enableServerComponentKeys = true;
|
||||
export const enableServerComponentLogs = true;
|
||||
export const enableInfiniteRenderLoopDetection = false;
|
||||
export const enableEarlyReturnForPropDiffing = false;
|
||||
export const enableAddPropertiesFastPath = false;
|
||||
|
||||
export const renameElementSymbol = true;
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ export const disableDOMTestUtils = false;
|
||||
|
||||
export const disableDefaultPropsExceptForClasses = false;
|
||||
export const enableEarlyReturnForPropDiffing = false;
|
||||
export const enableAddPropertiesFastPath = false;
|
||||
|
||||
export const renameElementSymbol = false;
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ export const disableDOMTestUtils = false;
|
||||
|
||||
export const disableDefaultPropsExceptForClasses = false;
|
||||
export const enableEarlyReturnForPropDiffing = false;
|
||||
export const enableAddPropertiesFastPath = false;
|
||||
|
||||
export const renameElementSymbol = false;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ export const enableNoCloningMemoCache = __VARIANT__;
|
||||
export const retryLaneExpirationMs = 5000;
|
||||
export const syncLaneExpirationMs = 250;
|
||||
export const transitionLaneExpirationMs = 5000;
|
||||
export const enableAddPropertiesFastPath = __VARIANT__;
|
||||
|
||||
// Enable this flag to help with concurrent mode debugging.
|
||||
// It logs information to the console about React scheduling, rendering, and commit phases.
|
||||
|
||||
@@ -35,6 +35,7 @@ export const {
|
||||
favorSafetyOverHydrationPerf,
|
||||
disableDefaultPropsExceptForClasses,
|
||||
enableNoCloningMemoCache,
|
||||
enableAddPropertiesFastPath,
|
||||
} = dynamicFeatureFlags;
|
||||
|
||||
// On WWW, __EXPERIMENTAL__ is used for a new modern build.
|
||||
|
||||
Reference in New Issue
Block a user