[iOS] Skip no-op ellipsis recolor in processTruncatedAttributedText - #58281
[iOS] Skip no-op ellipsis recolor in processTruncatedAttributedText#58281cezarywojcik wants to merge 2 commits into
Conversation
|
Hi @cezarywojcik! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
Summary:
RCTTextLayoutManager processTruncatedAttributedText:matches the truncated (ellipsis) range's color attributes to the character before it, so a truncated line's "…" doesn't carry a foreground/background color from the trimmed text (added in fcb6cdc / #39408). It does this by unconditionally removing and re-addingNSForegroundColorAttributeName/NSBackgroundColorAttributeNameover the truncated range on every draw. That storage edit invalidates the layout TextKit just computed and re-typesets the paragraph insidedrawAttributedString:— even when the attributes are already correct, which is the case for every single-color<Text numberOfLines={...}>.This is expensive during continuous layout (e.g. resizing a split-view pane on iPad, where every visible row redraws per frame). On an iPad Pro (M5), Release build, ~20 ellipsized rows: an Instruments Time Profiler trace showed 72.8% of the paragraph draw-path cost inside this method's forced re-typeset (2.29s of a 3.15s draw path over the session). With the skip, observed p95 frame time during pane resizes dropped from 66ms to 42ms and worst frame from 100ms to 66ms, with identical rendering.
The change: before editing, check whether the truncated range already uniformly carries the attribute found at
characterRange.location - 1, and skip the remove/add when it does. Multi-color truncated lines keep the existing recolor behavior, preserving #39408.Related: #58101 defers the same edit out of the line-fragment enumeration to fix a crash with composed characters; this skip composes with that change (both reduce how often the storage is mutated mid-draw).
Changelog:
[IOS] [FIXED] - Avoid re-typesetting truncated single-color Text on every draw by skipping the no-op ellipsis recolor
Test Plan:
<Text numberOfLines={1}>and multilinenumberOfLines={3}, light/dark — rendering identical before/after; ellipsis color matching for multi-color text (the 【iOS】Fixes ellipsis carries background from trimmed text #39408 case) still applies._fillLayoutHole...re-typeset stacks under-[RCTParagraphTextView drawRect:]for single-color truncated text; unchanged behavior for multi-color text.