Bug 2052369 Comment 0 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

Every keystroke during prompt composition does O(doc) work across browser/components/multilineeditor and browser/components/urlbar.
S1-1: MultilineEditor value getter (multiline-editor.mjs#204) serializes the entire ProseMirror doc; _on_input (SmartbarInput.mjs#6117) reads it 2-3x per keystroke -> memoize per immutable doc identity and read once.
S1-2: #dispatchTransaction (multiline-editor.mjs#638; prevText=this.value #660) serializes the doc before the tr.docChanged guard (#674), so caret/selection changes also do a full serialize -> move prevText/nextText inside the docChanged block.
S1-3: hasMention (MentionsPlugin.mjs#90) does a full-doc traversal per keystroke from _on_input (SmartbarInput.mjs#6166) -> track mention presence as plugin state.
S1-4: _on_keyup (SmartbarInput.mjs#6605) is async, allocating a microtask per key release -> make it sync and extract the deferred (Enter) path into an async helper.
S1-5: #posFromTextOffset (multiline-editor.mjs#928; doc.descendants #937) does up to 3 full-doc walks per setSelectionRange (callers #240/#358/#362) -> compute in one combined pass.
NEW-1: _on_input unconditionally calls startQuery (SmartbarInput.mjs#6235); during pre-first-send composition _suppressStartQuery is false, so the full async controller.startQuery (#2947) runs undebounced into UrlbarController.startQuery, and in-progress prompt text leaks into providers -> debounce and suppress startQuery during pre-send composition.

Part of the Smart Window happy-path performance work (Jira AIPLAT-1022); consolidated from the June 2026 profiling pass. Full finding specs and profile links: see the meta bug. Rolls up findings: S1-1, S1-2, S1-3, S1-4, S1-5, NEW-1.
While a user composes a prompt, several operations do work proportional to the whole document on every keystroke, which is visible jank on slower CPUs.

- The multiline editor's value getter serializes the entire ProseMirror document, and the input handler reads it more than once per keystroke. Serialization also happens for caret and selection changes, because [`dispatchTransaction`](https://searchfox.org/mozilla-central/search?q=dispatchTransaction&path=multiline-editor.mjs) reads the value before the "document changed" guard.
- [`hasMention`](https://searchfox.org/mozilla-central/search?q=hasMention&path=MentionsPlugin.mjs) traverses the whole document on every keystroke.
- [`#posFromTextOffset`](https://searchfox.org/mozilla-central/search?q=posFromTextOffset&path=multiline-editor.mjs) walks the document up to three times per selection update.
- The keyup handler [`_on_keyup`](https://searchfox.org/mozilla-central/search?q=_on_keyup&path=SmartbarInput.mjs) is async, allocating a microtask per key release.
- Most significantly, the input handler unconditionally issues a full address-bar provider query through [`startQuery`](https://searchfox.org/mozilla-central/search?q=startQuery&path=SmartbarInput.mjs); during pre-send composition this runs undebounced on every keystroke, and the in-progress prompt text is pushed through the provider path.

**AI Suggested fix.** Memoize the serialized value by document identity and read it once; move the value read inside the "document changed" guard; track mention presence as plugin state; resolve selection offsets in a single walk; make the keyup handler synchronous; and debounce the provider query, suppressing it entirely during pre-send composition so the prompt text does not leak into providers.

Back to Bug 2052369 Comment 0