Skip to content

Commit

Permalink
perf(sourcemap): lazy compute decoded mappings
Browse files Browse the repository at this point in the history
By deferring the decoding of the sourcemap mappings field, we can avoid
extra computation and garbage generation, both of which appear to save
a significant amount of time.

In my test application (using vite), I saw a reduction in total build
time of about 28.4%, and a reduction in peak heap size of 19.6% (706 MB)

Project Info:
* Node: v18.17.0
* Vite v4.4.7
* Rollup v3.26.3
* Module Count: 5490 modules transformed
* Chunk Count: 54 chunks rendered

Before:
* Average vite build time (5 runs): 30.89 seconds
* Average peak heap size (5 runs): 3594.83 MB
* Time spent in GC: ~13.7 seconds
* Time spent in `decode()`: 3.11 seconds

After:
* Average vite build time (5 runs): 22.13 seconds
* Average peak heap size (5 runs): 2888.2 MB
* Time spent in GC: ~5.9 seconds
* Time spent in `decode()`: 1.70 seconds
  • Loading branch information
Adam Hines committed Jul 27, 2023
1 parent dc89523 commit e3b636b
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions src/utils/decodedSourcemap.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { decode } from '@jridgewell/sourcemap-codec';
import { decode, type SourceMapMappings } from '@jridgewell/sourcemap-codec';
import type {
ExistingDecodedSourceMap,
ExistingRawSourceMap,
Expand All @@ -22,7 +22,27 @@ export function decodedSourcemap(map: Input): ExistingDecodedSourceMap | null {
};
}

const mappings = typeof map.mappings === 'string' ? decode(map.mappings) : map.mappings;
const decodedMap = {
...(map as ExistingRawSourceMap | ExistingDecodedSourceMap),
mappings: undefined as unknown as SourceMapMappings
};

return { ...(map as ExistingRawSourceMap | ExistingDecodedSourceMap), mappings };
const origMappings = map.mappings;
let memoizedMappings: SourceMapMappings | undefined;

Object.defineProperty(decodedMap, 'mappings', {
enumerable: true,
get() {
if (memoizedMappings) {
return memoizedMappings;
}
memoizedMappings = typeof origMappings === 'string' ? decode(origMappings) : origMappings;
return memoizedMappings;
},
set(value) {
memoizedMappings = value;
}
});

return decodedMap;
}

0 comments on commit e3b636b

Please sign in to comment.