From c702bbf853225f13d1d7d616a71d70d8ae146fc9 Mon Sep 17 00:00:00 2001 From: Rob Hogan Date: Sat, 26 Sep 2026 08:52:11 +0100 Subject: [PATCH] Consumer: Don't decode every source map segment twice `MappingsConsumer` decoded the VLQ of every mapping twice - once through its cache and once more with the result discarded - since the consumer was added in ccd508c4a. This removes the second call. `composeSourceMaps` with a bundle map and its Hermes map is 13.6% faster (95% CI 13.3-13.8%; 2,088ms -> 1,801ms on our benchmark app*), with byte-identical output. Composition memory is within 0.2% (-1MB*). | | Time (median) | vs previous | vs `main` | Composition memory* | vs previous | vs `main` | Peak RSS | |---|---|---|---|---|---|---|---| | `main` | 2,088ms (2,082 to 2,094) | | | 1,070MB (1,070 to 1,070) | | | 1,664MB | | This diff | 1,801ms (1,794 to 1,806) | -13.6% (-13.8 to -13.3) | -13.6% (-13.8 to -13.3) | 1,069MB (1,069 to 1,069) | -0.1% (-0.2 to -0.1) | -0.1% (-0.2 to -0.1) | 1,663MB | ## Changelog ``` - **[Performance]**: Don't decode source map segments twice in `metro-source-map`'s `Consumer` ``` ## Test plan ``` yarn jest packages/metro-source-map packages/metro-symbolicate yarn flow check ``` \* Benchmark: Mattermost Mobile 2.45.0 (React Native 0.83.9, Metro 0.83.7), iOS release bundle, unminified: 7,086 sources, 52.6MB bundle, 82.4MB flat source map. Composed with its `hermesc -O -output-source-map` map (hermes-compiler 0.14.1; 10.7MB, 1.84M segments). Timings are `composeSourceMaps` alone, excluding JSON parsing, over 105 rounds on Node 22.13.1 on an M5 Pro; each round runs `main`, every diff in this stack and a memory baseline, in a shuffled order. Figures are medians with 95% bootstrap confidence intervals - for changes, of the per-round paired ratio. Composition memory is peak RSS less that of the same process parsing both maps without composing them (594MB). --- packages/metro-source-map/src/Consumer/MappingsConsumer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/metro-source-map/src/Consumer/MappingsConsumer.js b/packages/metro-source-map/src/Consumer/MappingsConsumer.js index bae03c4234..54777ef14a 100644 --- a/packages/metro-source-map/src/Consumer/MappingsConsumer.js +++ b/packages/metro-source-map/src/Consumer/MappingsConsumer.js @@ -140,7 +140,6 @@ export default class MappingsConsumer originalColumnDelta, nameIndexDelta, ] = decodedVlqValues; - decodeVlq(mappingRaw); invariant(generatedColumnDelta != null, 'Invalid generated column delta'); generatedColumn = add(generatedColumn, generatedColumnDelta); const mapping: {...Mapping, ...} = {