Scope IME display attribute enumeration to the edited ranges - #11872
Open
akon47 wants to merge 1 commit into
Open
Scope IME display attribute enumeration to the edited ranges#11872akon47 wants to merge 1 commit into
akon47 wants to merge 1 commit into
Conversation
TextServicesDisplayAttributePropertyRanges.OnEndEdit enumerated the display
attribute property with a null target range, which enumerates the property
over the entire document. The property accumulates a range per previously
composed run, so both the enumeration and the COM round trip it costs per
range grow with the length of the document - on every keystroke.
This only shows up with IMEs that set display attributes (for example the
modern Korean TSF IME, which underlines the composition). Measured on a
1,200 character RichTextBox while typing with that IME, a single OnEndEdit
call enumerated 1,077 ranges of which exactly one carried an attribute, and
blocked the UI thread for about 3 seconds.
Use GetPropertyUpdate(editRecord) to obtain the ranges this edit actually
changed and enumerate the property within each of them, which is what the
base class TextServicesPropertyRanges.OnEndEdit already does; this override
had lost that scoping. GetPropertyUpdate is promoted from private to
protected so the override can reuse it.
Measured with an automated SendInput macro typing "안녕하세요 " 300 times
into a RichTextBox (Windows 11 26200, .NET 8, x64 Release):
before: mean 181.3 ms/iteration, max 3577.6 ms,
13 UI thread stalls totalling 15,898 ms
after: mean 100.9 ms/iteration, max 127.4 ms,
1 stall of 53 ms
which matches the legacy IME baseline (mean 101.5 ms, no stalls) on the same
harness. The composition underline and the Hanja candidate window continue to
render correctly.
Contributes to dotnet#7397
Author
|
@dotnet-policy-service agree |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the typing lag reported in #7397.
Cause
TextServicesDisplayAttributePropertyRanges.OnEndEditenumerates the display attribute property with a null target range, which enumerates it over the whole document:The property accumulates a range per previously composed run, so both the enumeration and the COM round trip it costs per range grow with document length — on every keystroke.
Only IMEs that set display attributes hit this (for example the modern Korean TSF IME, which underlines the composition). Measured on a 1,200 character
RichTextBox, a singleOnEndEditenumerated 1,077 ranges of which exactly 1 carried an attribute, blocking the UI thread for ~3 seconds.Fix
Use
GetPropertyUpdate(editRecord)to obtain the ranges this edit actually changed and enumerate the property within each of them — which is what the base classTextServicesPropertyRanges.OnEndEditalready does. This override had lost that scoping.GetPropertyUpdateis promoted fromprivatetoprotectedso the override can reuse it.Measurement
SendInputmacro typing안녕하세요300 times into aRichTextBox(Windows 11 10.0.26200, .NET 8, x64 Release):The same harness with the IME in English mode showed no stalls before or after, confirming the cost is in the composition path.
Composition underline and the Hanja candidate window continue to render correctly, including mid-document, while scrolled, and immediately after fast typing.
Notes
PresentationFramework4.8.9340.0), consistent with the original report that 4.8 is affected.IMECompositionTraceTarget) plus stack sampling during the stalls; analysis was done with the help of Claude Code, and every number above is a measurement from an actual run on my machine.Microsoft Reviewers: Open in CodeFlow