Skip to content

Commit b1a1cb1

Browse files
author
Brian Vaughn
authored
DevTools: Lazily parse indexed map sections (#22415)
Indexed maps divide nested source maps into sections, annotated with a line and column offset. Since these sections are JSON and can be quickly parsed, we can easily separate them without doing the heavier base64 and VLQ decoding process. This PR updates our sourcemap parsing code to defer parsing of an indexed map section until we actually need to retrieve mappings from it.
1 parent a01cdbf commit b1a1cb1

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

packages/react-devtools-shared/src/hooks/SourceMapConsumer.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {decode} from 'sourcemap-codec';
1111

1212
import type {
1313
IndexSourceMap,
14+
IndexSourceMapSection,
1415
BasicSourceMap,
1516
MixedSourceMap,
1617
} from './SourceMapTypes';
@@ -34,7 +35,7 @@ export type SourceMapConsumerType = {|
3435
type Mappings = Array<Array<Array<number>>>;
3536

3637
export default function SourceMapConsumer(
37-
sourceMapJSON: MixedSourceMap,
38+
sourceMapJSON: MixedSourceMap | IndexSourceMapSection,
3839
): SourceMapConsumerType {
3940
if (sourceMapJSON.sections != null) {
4041
return IndexedSourceMapConsumer(((sourceMapJSON: any): IndexSourceMap));
@@ -137,13 +138,22 @@ function BasicSourceMapConsumer(sourceMapJSON: BasicSourceMap) {
137138
}: any): SourceMapConsumerType);
138139
}
139140

141+
type Section = {|
142+
+generatedColumn: number,
143+
+generatedLine: number,
144+
+map: MixedSourceMap,
145+
146+
// Lazily parsed only when/as the section is needed.
147+
sourceMapConsumer: SourceMapConsumerType | null,
148+
|};
149+
140150
function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
141151
let lastOffset = {
142152
line: -1,
143153
column: 0,
144154
};
145155

146-
const sections = sourceMapJSON.sections.map(section => {
156+
const sections: Array<Section> = sourceMapJSON.sections.map(section => {
147157
const offset = section.offset;
148158
const offsetLine = offset.line;
149159
const offsetColumn = offset.column;
@@ -161,7 +171,8 @@ function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
161171
// The offset fields are 0-based, but we use 1-based indices when encoding/decoding from VLQ.
162172
generatedLine: offsetLine + 1,
163173
generatedColumn: offsetColumn + 1,
164-
sourceMapConsumer: new SourceMapConsumer(section.map),
174+
map: section.map,
175+
sourceMapConsumer: null,
165176
};
166177
});
167178

@@ -229,6 +240,11 @@ function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
229240
);
230241
}
231242

243+
if (section.sourceMapConsumer === null) {
244+
// Lazily parse the section only when it's needed.
245+
section.sourceMapConsumer = new SourceMapConsumer(section.map);
246+
}
247+
232248
return section.sourceMapConsumer.originalPositionFor({
233249
columnNumber,
234250
lineNumber,

0 commit comments

Comments
 (0)