With word wrap on, VisibleByteRange mapped the viewport TOP from visual to logical line space (WrapIndex.LineForVisual) but left the viewport BOTTOM as the raw visual-line number and used it as a LOGICAL index. The window therefore fetched (viewport lines + every wrapped line above the viewport) of real text: an over-fetch that grew without bound with scroll depth. Measured on a 2.9 MB file with wrap on: the shaped window was ~3.7 KB at 300 KB depth but ~17.4 KB at 2.8 MB depth, costing 12 ms of shaping and 40 ms of frame draw per frame there — scrolling visibly degraded the further down the file you got. Map the bottom through LineForVisual exactly like the top: the logical line containing the viewport's bottom visual line is the correct end, and since each logical line yields at least one visual line the window still always covers the viewport. The fetch is now viewport-bounded at every depth (window flat at ~1 KB across 300 KB..2.8 MB in the test file; deep frames drop from 40 ms to <4 ms). Also drop the instrumentation added while diagnosing. |
||
|---|---|---|
| .. | ||
| browser | ||
| editor | ||
| io/pool | ||
| perf | ||
| test/e2e | ||
| ui | ||