Repository navigation
Skip the clear background attribute on iOS Text - #59207
Open
hryhoriiK97 wants to merge 1 commit into
Open
hryhoriiK97 wants to merge 1 commit into
hryhoriiK97 wants to merge 1 commit into
Conversation
TextAttributes default backgroundColor to clearColor(), so every fragment of every Text got NSBackgroundColorAttributeName set to a transparent color, and TextKit computed and filled the background rects of each run on every draw without changing any pixel. Set the attribute only for a background color that isn't clear. Co-Authored-By: Claude Opus 5.5 <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:
RCTNSTextAttributesFromTextAttributes(ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm) builds the attributes TextKit draws each text fragment with.Current behavior. It sets
NSBackgroundColorAttributeNamewhenevertextAttributes.backgroundColoris set oropacityis set.TextAttributes::defaultTextAttributes()setsbackgroundColortoclearColor(), so every fragment of every<Text>gets a transparent background attribute, including text that never asked for a background. On every draw,NSLayoutManagerthen computes the rects of each run carrying that attribute and fills them with the clear color, which changes no pixels. In a Time Profiler trace of mounting 1000 labels on a device, this background pass was about a third of-[RCTTextLayoutManager drawAttributedString:...].With this change. The attribute is set only when the background color is set and is not
clearColor(). A clear background draws nothing, so the pixels are the same, and TextKit skips the background pass for text without a background. Text with a visible background color keeps the attribute as before, including withopacity. A nested<Text>withbackgroundColor: 'transparent'inside a parent with a background renders the same, since each fragment carries its own attributes. The other reader of the attribute,processTruncatedAttributedText:inRCTTextLayoutManager, already handles it being absent.Changelog:
[IOS] [CHANGED] - Text without a background color no longer draws a transparent background
Test Plan:
node scripts/clang-format.js --checkon the changed file passes.xcodebuildin Release and run on a physical iPhone 15 Pro (iOS 26.6.1).boxShadow, are byte-identical in the list area with and without the change.ScrollView, each aViewwrapping aText, with three contents (plain, bordered card with shadow props, and the card withboxShadow). Timed: the total time in-[RCTParagraphTextView drawRect:]in the display pass after each mount, and the time from the end of the mount to the CoreAnimation commit, which contains that pass. The two arms are the same binary with the change switched by an environment variable. 20 items were mounted ten times per content per launch, in the order before, after, after, before. 1000 items were mounted five times per content per launch, in two series in opposite orders (before, after, after, before, then after, before, before, after), which gave the same numbers. The presses were driven by Argent on the physical iPhone. iPhone 15 Pro, Release, medians:🤖 Generated with Claude Code