perf(@angular/build): avoid full JSON parsing when updating sourcemap ignore list - #34040
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a fast-path optimization to update sourcemaps with the Chrome DevTools ignore list extension without fully parsing and stringifying the JSON. It adds helper functions extractSources and updateSourcemapFast to locate the "sources" array and inject the ignore list. The review feedback highlights three key issues: first, checking contents.includes(IGNORE_LIST_BYTES) to skip processing entirely can lead to silent bugs if the ignore list identifier is present in the source code content, so it should only bypass the fast path; second, the fallback slow path should check if the ignore list is already present in the parsed map to avoid duplicate insertions; and third, the parsed array in extractSources should be validated to ensure all elements are strings to prevent potential runtime errors.
… ignore list Previously, the sourcemap ignore-list plugin parsed the entire generated sourcemap buffer into a JavaScript object via JSON.parse and re-serialized it via JSON.stringify to inject x_google_ignoreList. In typical applications, sourcemap files range from 2 MB to 10 MB+ each. The sources array constitutes less than 1% of the total file size, with the vast majority of the payload comprised of sourcesContent and VLQ-encoded mappings. Parsing and re-stringifying this large structure generates significant V8 heap churn (5x to 6x transient allocations per sourcemap) and incurs 20 ms to 60 ms of single-threaded blocking time per chunk. To eliminate redundant parsing and serialization overhead: - Scan the buffer to extract and parse only the sources JSON array. - Determine the node modules ignore list indices using the extracted sources array. - Splice the serialized x_google_ignoreList property directly into the output buffer adjacent to the root object delimiter without parsing or allocating intermediate strings for sourcesContent or mappings. - Gracefully fall back to full JSON parsing and serialization if non-standard JSON formatting is encountered. In benchmarks on 2.4 MB to 10.4 MB sourcemap files, ignore-list processing dropped from 20.3 ms to 0.60 ms (33.9x faster) and 60.2 ms to 2.27 ms (26.5x faster), respectively, while reducing heap churn by more than 99%.
f8e5483 to
e5ab123
Compare
Previously, the sourcemap ignore-list plugin parsed the entire generated sourcemap buffer into a JavaScript object via
JSON.parseand re-serialized it viaJSON.stringifyto injectx_google_ignoreList.In typical applications, sourcemap files range from 2 MB to 10 MB+ each. The
sourcesarray constitutes less than 1% of the total file size, with the vast majority of the payload comprised ofsourcesContentand VLQ-encodedmappings. Parsing and re-stringifying this large structure generates significant V8 heap churn (5x to 6x transient allocations per sourcemap) and incurs 20 ms to 60 ms of single-threaded blocking time per chunk.To eliminate redundant parsing and serialization overhead:
sourcesJSON array.sourcesarray.x_google_ignoreListproperty directly into the output buffer adjacent to the root object delimiter without parsing or allocating intermediate strings forsourcesContentormappings.In benchmarks on 2.4 MB to 10.4 MB sourcemap files, ignore-list processing dropped from 20.3 ms to 0.60 ms (33.9x faster) and 60.2 ms to 2.27 ms (26.5x faster), respectively, while reducing heap churn by more than 99%.