Skip to content

Commit c0268a8

Browse files
authored
Merge pull request Expensify#67417 from callstack-internal/perf/recomputeDerivedValue-performance-improvements
2 parents 2cf7c53 + c731ed7 commit c0268a8

2 files changed

Lines changed: 26 additions & 23 deletions

File tree

src/libs/actions/OnyxDerived/configs/reportAttributes.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,37 +51,41 @@ export default createOnyxDerivedValueConfig({
5151
isFullyComputed = false;
5252
}
5353

54+
// if we already computed the report attributes and there is no new reports data, return the current value
55+
if ((isFullyComputed && !sourceValues) || !reports) {
56+
return currentValue ?? {reports: {}, locale: null};
57+
}
58+
5459
const reportUpdates = sourceValues?.[ONYXKEYS.COLLECTION.REPORT] ?? {};
5560
const reportMetadataUpdates = sourceValues?.[ONYXKEYS.COLLECTION.REPORT_METADATA] ?? {};
5661
const reportActionsUpdates = sourceValues?.[ONYXKEYS.COLLECTION.REPORT_ACTIONS] ?? {};
5762
const reportNameValuePairsUpdates = sourceValues?.[ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS] ?? {};
5863
const transactionsUpdates = sourceValues?.[ONYXKEYS.COLLECTION.TRANSACTION];
5964
const transactionViolationsUpdates = sourceValues?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS];
60-
// if we already computed the report attributes and there is no new reports data, return the current value
61-
if ((isFullyComputed && !sourceValues) || !reports) {
62-
return currentValue ?? {reports: {}, locale: null};
63-
}
6465

6566
let dataToIterate = Object.keys(reports);
6667
// check if there are any report-related updates
6768

68-
const reportUpdatesRelatedToReportActions: string[] = [];
69+
const reportUpdatesRelatedToReportActions = new Set<string>();
70+
71+
for (const actions of Object.values(reportActionsUpdates)) {
72+
if (!actions) {
73+
continue;
74+
}
6975

70-
Object.keys(reportActionsUpdates).forEach((reportKey) => {
71-
Object.keys(reportActionsUpdates[reportKey] ?? {}).forEach((reportActionKey) => {
72-
const reportAction = reportActions?.[reportKey]?.[reportActionKey];
76+
for (const reportAction of Object.values(actions)) {
7377
if (reportAction?.childReportID) {
74-
reportUpdatesRelatedToReportActions.push(`${ONYXKEYS.COLLECTION.REPORT}${reportAction.childReportID}`);
78+
reportUpdatesRelatedToReportActions.add(`${ONYXKEYS.COLLECTION.REPORT}${reportAction.childReportID}`);
7579
}
76-
});
77-
});
80+
}
81+
}
7882

7983
const updates = [
8084
...Object.keys(reportUpdates),
8185
...Object.keys(reportMetadataUpdates),
8286
...Object.keys(reportActionsUpdates),
8387
...Object.keys(reportNameValuePairsUpdates),
84-
...reportUpdatesRelatedToReportActions,
88+
...Array.from(reportUpdatesRelatedToReportActions),
8589
];
8690

8791
if (isFullyComputed) {

src/libs/actions/OnyxDerived/index.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,23 @@ function init() {
6464
}
6565
};
6666

67+
// Create context once outside the function, swap values inline to avoid overhead of creating new objects frequently
68+
const context: DerivedValueContext<typeof key, typeof dependencies> = {
69+
currentValue: undefined,
70+
sourceValues: undefined,
71+
areAllConnectionsSet: false,
72+
};
73+
6774
const recomputeDerivedValue = (sourceKey?: string, sourceValue?: unknown, triggeredByIndex?: number) => {
6875
// If this recompute was triggered by a connection callback, check if it initializes the connection
6976
if (triggeredByIndex !== undefined) {
7077
checkAndMarkConnectionInitialized(triggeredByIndex);
7178
}
7279

73-
const context: DerivedValueContext<typeof key, typeof dependencies> = {
74-
currentValue: derivedValue,
75-
sourceValues: undefined,
76-
areAllConnectionsSet,
77-
};
80+
context.currentValue = derivedValue;
81+
context.areAllConnectionsSet = areAllConnectionsSet;
82+
context.sourceValues = sourceKey && sourceValue !== undefined ? {[sourceKey]: sourceValue} : undefined;
7883

79-
// If we got a source key and value, add it to the sourceValues object
80-
if (sourceKey && sourceValue !== undefined) {
81-
context.sourceValues = {
82-
[sourceKey]: sourceValue,
83-
};
84-
}
8584
// @ts-expect-error TypeScript can't confirm the shape of dependencyValues matches the compute function's parameters
8685
const newDerivedValue = compute(dependencyValues, context);
8786
Log.info(`[OnyxDerived] updating value for ${key} in Onyx`);

0 commit comments

Comments
 (0)