Repository navigation
Trim NSAttributedString construction for text on iOS - #59154
Open
hryhoriiK97 wants to merge 1 commit into
Open
hryhoriiK97 wants to merge 1 commit into
hryhoriiK97 wants to merge 1 commit into
Conversation
Building the NSAttributedString for a paragraph copied every fragment by value, added the event emitter in a second pass over the fragment, wrapped a single fragment in an enclosing mutable string, allocated a paragraph style whether or not one was needed, and computed the font size multiplier twice. Do none of that; the attributes produced per run are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This branch has not been deployed
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:
RCTNSAttributedStringFromAttributedString(ReactCommon/react/renderer/textlayoutmanager/platform/ios/.../RCTAttributedTextUtils.mm) converts a paragraph'sAttributedStringinto theNSAttributedStringTextKit lays out and draws. It runs once per paragraph per measurement when the attributed-string cache misses, so for a screen of distinct labels it runs once per label.Current behavior. Per fragment, the conversion:
getFragments()withfor (auto fragment : ...), copying eachFragment: itsstd::string, itsTextAttributes, and aShadowViewwith threeshared_ptrmembers (props, event emitter, state), so three atomic retain/release pairs per fragment;addAttributes:range:pass, which splits and re-merges the attribute runs TextKit just created;NSMutableParagraphStylebefore knowing whether any paragraph attribute was set, discarding it for the common unaligned, default-line-height case;lineHeightis set, which withdynamicTypeRampmeans twoUIFontMetricsround trips;NSMutableAttributedStringand appended each fragment to it, even for the single-fragment paragraph that most labels are;NSStringfor the font family even when it is unset and resolves to the default family anyway.With this change. Fragments are iterated by reference; the event emitter goes into the initial attribute dictionary; the paragraph style is created only when one of its fields is set; the multiplier is computed once and passed to the font resolution; a single-fragment paragraph returns the fragment's string directly; the family string is skipped when unset. The attributes attached to each run are the same as before, in the same ranges.
Changelog:
[IOS] [CHANGED] - Build a paragraph's NSAttributedString with fewer copies and allocations per text fragment
Test Plan:
node scripts/clang-format.js --checkon the changed file passes.xcodebuildfor the iPhone 16 Pro simulator (Debug) and for a physical iPhone 15 Pro (Release); the Text examples render as before.-[RCTTextLayoutManager measureAttributedString:...], summed per transaction. iPhone 16 Pro simulator, Debug, medians of 3 to 5 runs:fontFamily: 'Avenir'Conversion is about a quarter of the paragraph's measurement time, so this is roughly 5% of the shadow-thread layout cost of a text-heavy commit. TextKit layout itself (the remaining three quarters) is unchanged, as expected.
🤖 Generated with Claude Code