getChangedRanges rebuilds the inverted mapping for every range
Author: issacgergesCreated Sep 8, 2026Updated Sep 8, 2026
Labelsstatus: triagearea: corecomplexity: easyimpact: medium
Affected Packages
core, extension-link
Tiptap Version
3.31.3
Browser Used
Not browser-specific
What happened?
getChangedRanges in @tiptap/core calls mapping.invert() twice and mapping.slice(index) twice inside its inner loop, once per range. invert() allocates a new Mapping with one map per step, and the Link extension's autolink plugin calls getChangedRanges on every transaction.
Expected Behavior
mapping.invert() is computed once per call and mapping.slice(index) once per step map.
Reproducible Example URL (Optional)
No response
Additional Context (Optional)
Example repro:
const transform = new Transform(doc)
for (let i = 0; i < 4000; i += 1) transform.insert(1 + i, schema.text('a'))
getChangedRanges(transform) // ~300 msSource: ueberdosis/tiptap