Skip to content

Commit

Permalink
Resolver perf: Optimise package exports flattenLegacySubpathValues
Browse files Browse the repository at this point in the history
…(1/n) (#1318)

Summary:
Pull Request resolved: #1318

The performance results from this stack are based on replaying the ~3000 resolutions performed during bundling RN Tester directly through `DependencyGraph.resolveDependency`. The baseline resolution time is ~1500ms on an M1 Max. (Internal: details in test plan)

This is a self-contained optimsation to the `flattenLegacySubpathValues` step as part of exports map normalisation, which takes over 20% (360ms) of total resolver CPU time over 655 calls due largely to repeated object allocations and spreads. By mutating an intermediate object instead we get this down to ~16ms.

Note that this still preserves key order - export maps are ordered.

This reduces total resolution time from 1540ms -> 1171ms (-23%)

Reviewed By: huntie

Differential Revision: D56701232

fbshipit-source-id: f2195e84b018c695ebe627e479ae235fba994a1e
  • Loading branch information
robhogan authored and facebook-github-bot committed Aug 12, 2024
1 parent ec3f4fb commit 021e890
Showing 1 changed file with 17 additions and 15 deletions.
32 changes: 17 additions & 15 deletions packages/metro-resolver/src/PackageExportsResolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,21 +202,23 @@ function flattenLegacySubpathValues(
exportMap: ExportMap | ExportMapWithFallbacks,
createConfigError: (reason: string) => Error,
): ExportMap {
return Object.keys(exportMap).reduce((result: ExportMap, subpath: string) => {
const value = exportMap[subpath];

// We do not support empty or nested arrays (non-standard)
if (Array.isArray(value) && (!value.length || Array.isArray(value[0]))) {
throw createConfigError(
'Could not parse non-standard array value in "exports" field.',
);
}

return {
...result,
[subpath]: Array.isArray(value) ? value[0] : value,
};
}, {});
return Object.entries(exportMap).reduce(
(result, [subpath, value]) => {
// We do not support empty or nested arrays (non-standard)
if (Array.isArray(value)) {
if (!value.length || Array.isArray(value[0])) {
throw createConfigError(
'Could not parse non-standard array value in "exports" field.',
);
}
result[subpath] = value[0];
} else {
result[subpath] = value;
}
return result;
},
{} as {[subpathOrCondition: string]: string | ExportMap | null},
);
}

/**
Expand Down

0 comments on commit 021e890

Please sign in to comment.