Overhaul glyph grid loading and scroll pipeline - #161
Merged
Conversation
- rework grid around virtualized rows with batched frame loads; switch TypeScript formatting to oxfmt - batch glyph loads with in-flight dedup (createBatchRequest -> Font.loadGlyphs) - detect projection component divergence structurally in shift-font: 306-glyph cold reads 2,160ms -> 245ms; characterization tests pin exact_source_components across compatible/sparse/nested/anchor cases - derive the glyph object index as a lazy tracked computed; snapshot apply cost flat instead of accreting with residency - getGlyphPreviews bridge read: svg path + advance printed at a location, 5-15x lighter on the wire than full snapshots - two-lane grid loading: previews chase the live scroll position, full models load only after the window settles; latest-window-wins - byte-budgeted GlyphPreviewCache (256MiB) with viewport-outward warm-up; no font-size cliff - inverse-sticky pinned frame: compositor-enforced, blank scroll regions impossible; atomic complete-frame display with placeholder cells - memoized rows with content-aware comparator; deferred pending windows - temporary phase instrumentation across bridge, workspace host, coordinator, store, and grid (removal tracked in the projection ticket) Baselines and design: vault notes "Reference - Glyph Pipeline Performance Baselines 2026-07", "Ticket - Glyph Projection Location-Independence Invariants", "Ticket - Atomic Glyph Grid Frames and Retained Glyph Acquisition", "Research - Glyph Grid Native-Feel Rendering at 65k".
Strips the phase timers and console probes used to isolate the glyph loading bottlenecks: projection_timing in shift-font, get_glyph_snapshots timers in the bridge, workspace-host handler timers and the payload probe, [glyph-rpc]/[glyph-apply]/[glyph-read]/[glyph-load]/[glyph-frame]/ [glyph-blank] renderer logs, and the first-frame-ready log. Revert this commit to restore the full measurement chain; the reading guide lives in docs/architecture/glyph-pipeline-performance.md and the recorded baselines in the vault performance reference.
kostyafarber
commented
Jul 26, 2026
kostyafarber
commented
Jul 26, 2026
kostyafarber
commented
Jul 26, 2026
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.
Summary
End-to-end rework of how the glyph grid loads, schedules, and presents glyphs, driven by layered instrumentation at every stage (Rust bridge → utility host → coordinator → store → grid). Measured start point: opening a ~340-glyph variable font produced 20+ concurrent window reads with 8–25s renderer read times and multi-second white-outs on scroll. End point: cold 306-glyph reads at 245ms, zero-contention scrolling, and a CJK grid (16.7k glyphs) that scrubs smoothly with bounded memory.
Rust / bridge
shift-font:glyph_projectionno longer resolves full component-closure geometry at every master to compare component structure — 306-glyph reads went from 2,160ms to 245ms (master_resolve1,842ms → 13ms). Characterization tests pinexact_source_componentsacross compatible, sparse, nested, and anchor-attachment cases.getGlyphSnapshotsunchanged in contract;GlyphComponents::from_layersnow borrows its layer map.getGlyphPreviews(glyphIds, location): svg path + advance printed at an internal location — 5–15× lighter on the wire than full snapshots (measured 25–35KB/glyph snapshots vs 2–6KB previews on CJK).Renderer model layer
Font.loadGlyphsbatches with in-flight dedup viacreateBatchRequest; redundantsettled()double-wait removed from the read path.GlyphPreviewCache: byte-budgeted (256MiB) location-keyed LRU; reads touch recency.Grid
nextWarmupChunk) — no font-size cliff; large fonts warm a halo around the viewport under the byte budget.Housekeeping
f6287fde; lessons + reconstruction guide (onegit revert) indocs/architecture/glyph-pipeline-performance.md.Test plan
pnpm checkgreen (Rust workspace + 471 renderer tests, incl. new suites forGlyphPreviewCache,nextWarmupChunk,batchRequest, projection characterization,get_glyph_previews).🤖 Generated with Claude Code