Skip to content

Fix: propagate elements metrics to their shadow nodes - #2802

Merged
kacperzolkiewski merged 13 commits into
software-mansion:mainfrom
kacperzolkiewski:shadowNodesState
Nov 12, 2025
Merged

kacperzolkiewski merged 13 commits into
software-mansion:mainfrom
kacperzolkiewski:shadowNodesState

Conversation

@kacperzolkiewski

@kacperzolkiewski kacperzolkiewski commented Oct 17, 2025 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes: #2796
Fixes: #2083

Previously, in the new architecture, shadow nodes for elements such as Circle, Rect and other SVG components were initialized with zero dimensions.
This caused issues with press interactions during move action. Yoga was unable to locate the corresponding shadow node resulting in the press event being canceled.
This PR updates the implementation to propagate each element’s actual native layout metrics to its shadow node.
By ensuring the shadow nodes reflect accurate geometry, Yoga can now correctly resolve touch targets fixing the issue where press actions were being incorrectly canceled.

Test Plan

Compatibility

OS Implemented
iOS ✅
MacOS ✅
Android ✅
Web ❌

Checklist

  • I have tested this on a device and a simulator
  • I added documentation in README.md
  • I updated the typed files (typescript)
  • I added a test for the API in the __tests__ folder

@kacperzolkiewski
kacperzolkiewski marked this pull request as ready for review October 21, 2025 10:08
@kacperzolkiewski kacperzolkiewski changed the title Propagate elements metrics to their shadow nodes Fix: propagate elements metrics to their shadow nodes Oct 21, 2025
Comment thread apple/RNSVGRenderable.h Resolved
Comment thread apple/RNSVGRenderable.mm Resolved
kacperzolkiewski and others added 6 commits November 12, 2025 12:30
Co-authored-by: Jakub Grzywacz <jaqbgrzy@gmail.com>
…iptor.h

Co-authored-by: Jakub Grzywacz <jaqbgrzy@gmail.com>
Co-authored-by: Jakub Grzywacz <jaqbgrzy@gmail.com>
…owNode.cpp

Co-authored-by: Jakub Grzywacz <jaqbgrzy@gmail.com>
…iptor.h

Co-authored-by: Jakub Grzywacz <jaqbgrzy@gmail.com>
@kacperzolkiewski
kacperzolkiewski merged commit 27eb9b0 into software-mansion:main Nov 12, 2025
9 checks passed
jakex7 added a commit that referenced this pull request Nov 25, 2025
jakex7 added a commit that referenced this pull request Nov 25, 2025
#2832)

This reverts commit 27eb9b0.

# Summary

Revert #2802 as it causes huge performance issues (#2831).

I'll create follow-up PRs re-introducing similar functionality.

## Test Plan

Use `PolygonBunny.tsx` example and see if JS thread dies.
jakex7 added a commit that referenced this pull request Nov 26, 2025
# Summary

It does the same thing as #2802 without affecting the performance. 

## Test Plan

I've added a few more examples that works the same as on web.
github-merge-queue Bot pushed a commit to software-mansion/react-native-reanimated that referenced this pull request Feb 27, 2026
## Summary

There was an issue with propagation of SVG dimensions before, which was
finally fixed in
[this](software-mansion/react-native-svg#2802)
PR. Thanks to these changes, we are able to support `%` in the same way
as for non-svg components and don't have to use the separate value
struct `SVGLength`.

## Test plan

I went through all SVG-related examples in the example app, adjusted
descriptions stating that `%` aren't supported (which isn't true
anymore) and tested that everything works as expected now.

---------

Co-authored-by: Jakub Wiśniewski <119816982+wisniewskij@users.noreply.github.com>
dylanjeffers added a commit to AudiusProject/apps that referenced this pull request Oct 9, 2026
…w architecture (#14652)

Two native fixes the new-architecture flip (#14648) needs. They ship in
1.5.188 on the old arch, so 1.5.189 is only the flag flip.

**Base: `fix/mobile-rntp-bridgeless` (#14647).** Rebased 2026-10-08 onto
the rebased #14647. Merge this into #14647, not main. The lockfiles were
checked after the rebase: `npm install` and `pod install` (old arch)
leave them unchanged, and `scripts/patch-package.sh` applies the Lottie
workspace patch with `--error-on-fail`. On old arch neither one changes
behavior. The svg change is behind `RCT_NEW_ARCH_ENABLED`, and the
Lottie method only exists on the Fabric component view.

## 1. react-native-svg 15.15.0 → 15.15.1 (CPU regression, #14648 blocker
6)
On Fabric, 15.15.0 (software-mansion/react-native-svg#2802) has every
SVG element push its bounds into a state update from `drawRect`
(`updateShadowNodeMetrics`). Each update is a `ShadowTree::commit`.
Reanimated 3's commit hook clones the tree and re-applies animated props
on every commit, which redraws the SVGs, so the loop never settles. On
an artist profile with nothing playing this held the app at ~150% CPU.

Evidence: an lldb breakpoint on `EventDispatcher::dispatchStateUpdate`
on the profile showed every state update coming from `-[RNSVGRenderable
updateShadowNodeMetrics]` / `-[RNSVGGroup updateShadowNodeMetrics]`,
called from `-[RNSVGSvgView drawRect:]`. Upstream reverted it in 15.15.1
(software-mansion/react-native-svg#2832, reported in #2831).

Result on the same profile (new arch, iOS 26.5 simulator, Release):
**151.5% → 20.2%**. Old arch on the same route is 16.3%.

`package-lock.json` changes only the nested
`packages/mobile/node_modules/react-native-svg` entry, which stays
nested because `metro.config.js` resolves it there. `Podfile.lock`
changes only the RNSVG version and checksum.

## 2. Lottie: opt out of Fabric view recycling (#14648 blocker 5)
lottie-react-native 7.3.4 keeps `autoPlay`/`loop` and the loaded
animation on the native container when Fabric recycles the view, while
`_props` goes back to defaults. After the first play, the play bar's
buffering spinner unmounts, its recycled view keeps playing, and its
`onAnimationFinish` reaches `AnimatedButton`, which dispatches `pause`.
The fix is `+shouldBeRecycled { return NO; }` via patch-package.

lottie-react-native is nested under `packages/mobile/node_modules`,
which the root `patch-package` run can't reach. So the patch lives in
`packages/mobile/workspace-patches/`, and `scripts/patch-package.sh`
applies it from the mobile workspace.

Verified on the simulator: previous session, 3 cold launches with no
self-pause, and again today on the full spike build (the first play kept
playing).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Path onPress prop not triggered since upgrading to expo 54 Can't use width or height of 100% with View inside ForeignObject

2 participants