Vue's Compiler Source-Map Rework Cuts CPU 30% and Fixes Wrong Line Numbers
A PR still under discussion in Vue's core repo swaps the compiler's source-map approach, cutting CPU by about 30%, memory by a third, and fixing over a dozen error-location misreporting bugs along the way.
The PR comes from johnsoncodehk, a Vue core team member, whose own library muggle-string is used.
First, what a source map is.
When writing .vue files, error stacks need to point back to the correct line and column, and breakpoints in browser dev tools must land on the .vue file. That relies on a mapping table generated during compilation, what the industry calls a source map.
The old generation method was roundabout: it used magic-string to modify the source string while separately recording a mapping with source-map-js, two systems running side by side.
Normally that's fine, but it tends to desynchronize whenever code insertion scenarios like multi-line expressions, v-for, or v-model come up.
The new approach changes the idea: each segment of generated code carries its own source range, and the mapping is assembled directly from the segments, with no separate maintenance.
What do the misalignments actually look like?
For a multi-line :class, the generated value gets pointed to the end of the previous line.
Inside a v-for line, generated start tags and text transformations point to the wrong line.
The directive wrapper compiled from v-model had no mapping at all in the old version, so breakpoints wouldn't jump to source.
Those scattered misalignments, over a dozen listed in the PR, span different compiler packages and get fixed together.
How much faster?
Hot-start CPU for the compile script dropped from 2,988 ms to 2,108 ms, a 29% reduction; peak memory fell from 848 MB to 563 MB.
Cold start went from 4,517 ms to 3,575 ms, with memory from 759 MB to 445 MB, a 40% drop.
Template compilation with inline mappings dropped 37%, with the biggest win in the parse phase, from 491 ms to 277 ms.
After parsing 1,297 components, retained heap went from 113.4 MB to 42.0 MB, a 63% reduction.
He gave the measurement setup: 1,297 .vue files, Node 24, Apple Silicon, a single run, and said these numbers shouldn't be treated as a ranking.
The install footprint also shrank a bit.
compiler-sfc's install tree went from 12 packages to 11, and source-map-js was pulled out of several compiler packages, leaving only one indirect dependency still using it.
On the browser bundle side, compiler-sfc is 5% smaller, compiler-vapor is 8% smaller, and the runtime global package is essentially unchanged.
It also fixed a few non-mapping issues.
await await foo() previously gave the outer layer an empty value; now it returns the correct result. Writing await in macro arguments previously threw a syntax error; now it renders normally. defineModel's options object used to be evaluated three times; now it's evaluated once.
The cost?
The most direct one: MagicString is no longer exported from @vue/compiler-sfc. The PR states this is an intentional breaking change. Tools like the online playground are affected; the fix is already in the main branch and will ship with the next release.
Another point: this change lands in a minor version, not a patch.
What's the status now?
After the PR was opened, the title changed twice, from a refactor to a performance optimization.
The next day the author re-ran the ecosystem tests: eight of sixteen suites were still red, including nuxt, vue-i18n, vuetify, and router.
He analyzed the causes himself: one category needs snapshot updates, another is that the new dependency was published too recently and got blocked by the package manager's release-age policy; re-running once the version ages will pass.
The scheduled baseline run that same day was all green, so the red part is caused by this change.
One more interesting detail: the branch name contains "cursor", and many commits list Cursor Agent as a co-author.
For a change affecting the entire Vue compilation chain, a portion of the commits is already written by an AI coding assistant, with humans reviewing and editing.
Is it worth reading? If you only write business code, you won't feel much short-term except to watch out for the MagicString note when upgrading.
If you're building build tools, an online playground, or wrapping the compiler yourself, this PR is worth reading from start to finish. It redoes "how generated code preserves its origin."
PR link: https://github.com/vuejs/core/pull/16126.
About me:
- Rural programmer (returned to the countryside in 2020, still there)
- Independent developer (working toward 1,000 small products)
- Technology observer (sharing programming techniques, industry news)
- 前端之虎陈随易 (self-appointed)
- My site:
https://yicode.tech
Top 1 of 2 from juejin.cn, machine-translated. The original thread is authoritative.
johnsoncodehk is truly badass
+1