perf(ios): improve codeblock - #663
Open
eszlamczyk wants to merge 2 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR optimizes iOS fenced code block rendering by removing repeated full-text layout work during measurement and drawing, replacing it with (1) an analytic height calculation and (2) a cached TextKit layout that drawRect: only paints from.
Changes:
- Replaced bounding-rect based height measurement with an analytic
lineCount * perLineHeightcalculation. - Added a cached
NSTextStorage/NSLayoutManager/NSTextContainerstack in the code content view and updated drawing to paint only the dirty glyph range. - Switched code-block content width calculation to read from TextKit’s
usedRectForTextContainer.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
What/Why?
Speeds up iOS code block rendering. Each fenced code block was being laid out from scratch multiple times per render:
boundingRectWithSizefor measurement anddrawAtPointfor drawing each spin up a throwaway TextKit stack, lay out the whole block, then tear it down again on everydrawRect:(scroll, redraw, streaming). tree-sitter parsing was never the bottleneck; the redundant layout was.Two changes, both in
ENRMCodeBlockContainerView.m:codeBlockLineHeight, or the font's natural line height), so the laid-out height is exactlylineCount * perLineHeight. This replacesmeasureHeightForCodeBlockNode:(height only) becomes essentially free.NSTextStorage/NSLayoutManager/NSTextContaineronce, when the attributed code changes, then caches them.drawRect:only callsdrawGlyphsForGlyphRange:atPoint:on the already-computed layout, clipped to the dirty rect so off-screen lines are skipped. Scroll/redraw/streaming no longer re-lay-out. Scroll content width falls out ofusedRectForTextContainerfor free, removing the separate width measurement pass. Same rendering enginedrawAtPointused internally, so output is pixel-identical.Measured gains (iOS simulator; 4 code blocks ~15 lines each — js/python/ts/go - with text between, whole document remounted 10x; per-render = total phase time per full document render):
Additionaly the perf win should be even greater while streaming
Testing
PR Checklist