Repository navigation
Commit 79a5629
Use a static cast for View nodes when building ShadowView layout metrics (#59290)
Summary:
`ShadowView`'s constructor reads the node's layout metrics through `layoutMetricsFromShadowNode`, which uses `dynamic_cast<const LayoutableShadowNode *>` to find out whether the node has layout. The differ builds a `ShadowView` for every child it visits when it slices a node's children, so this runs for every visited node on every commit, including the per-frame commits that update a ScrollView's content offset.
**Current behavior.** Every call pays for a `dynamic_cast`, which walks the type's inheritance information at runtime; for a `View`, the node's type is `ConcreteViewShadowNode<...>`, several levels below `LayoutableShadowNode`. In the profiles below, `__dynamic_cast` takes 19–21% of the differ's time while scrolling.
**With this change.** A node with the `ViewKind` trait takes a `static_cast`. `ShadowNodeTraits` documents `ViewKind` as "Inherits `ConcreteViewShadowNode<>` template", and `ConcreteViewShadowNode::BaseTraits()` is the only place that sets it; `ConcreteViewShadowNode` derives from `YogaLayoutableShadowNode`, so such a node is always a `LayoutableShadowNode` and the result is the same as the `dynamic_cast`'s. Other nodes (for example raw text) keep the checked cast. Core code already relies on the trait the same way: `PointerEventsProcessor`, `YogaLayoutableShadowNode` and `LayoutAnimationKeyFrameManager` check `ViewKind` and then `static_cast` the props to `ViewProps`.
## Changelog:
[GENERAL] [CHANGED] - Building a `ShadowView` for a View node no longer uses a `dynamic_cast` to read its layout metrics
Pull Request resolved: #59290
Test Plan:
- `clang-format --dry-run --Werror` on the changed file passes.
- `yarn fantom` (full suite, with the tester rebuilt from this change): 188 test suites and 3,288 tests pass (108 skipped by their configuration).
- RNTester built with `xcodebuild` in Release and run on a physical iPhone 15 Pro (iOS 26.6.1).
- **Measurement.** The two arms are the same binary with the change switched by a launch argument, in the order before, after, after, before. Interactions were driven by [Argent](https://github.com/software-mansion/argent) on the physical iPhone, under Instruments' Time Profiler. Values are main-thread sampled time per launch inside `calculateShadowViewMutations` (the differ), averaged over the 2 launches of each arm. iPhone 15 Pro, Release:
| RNTester screen, 10 flings (Playground chat: 40) | differ before | this PR | change | `__dynamic_cast` in the differ, before → this PR |
|---|--:|--:|--:|--:|
| Playground, chat of 500 messages | 338 ms | 280 ms | −17% | 64 → 14 ms |
| FlatList basic | 187 ms | 150 ms | −20% | 38 → 0 ms |
| SectionList scrollable | 296 ms | 290 ms | −2% | 63 → 10 ms |
SectionList is mostly bound by the JS thread and renders a different amount in each launch, so its differ time varied from 237 to 356 ms between launches of the same arm; the time in `__dynamic_cast` is the stable number there. The differ is 7–9% of the main thread's time on these screens. Mounting 1000 views five times took 24–31 ms of differ time per launch in both arms, too little for the profiler's 1 ms samples to show a difference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed By: christophpurrer
Differential Revision: D126687891
Pulled By: javache
fbshipit-source-id: 83440573d6fdb644843f3961a8e8ceade78756241 parent c1d8139 commit 79a5629
15 files changed
Lines changed: 41 additions & 3 deletions
File tree
- packages/react-native/ReactCommon/react/renderer
- core
- mounting
- scripts/cxx-api/api-snapshots
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
117 | 117 | | |
118 | 118 | | |
119 | 119 | | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
120 | 125 | | |
121 | 126 | | |
122 | 127 | | |
| |||
170 | 175 | | |
171 | 176 | | |
172 | 177 | | |
173 | | - | |
| 178 | + | |
174 | 179 | | |
175 | 180 | | |
176 | 181 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
122 | 123 | | |
123 | 124 | | |
124 | 125 | | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
125 | 135 | | |
126 | 136 | | |
127 | 137 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
17 | | - | |
| 16 | + | |
18 | 17 | | |
19 | 18 | | |
20 | 19 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1719 | 1719 | | |
1720 | 1720 | | |
1721 | 1721 | | |
| 1722 | + | |
1722 | 1723 | | |
1723 | 1724 | | |
1724 | 1725 | | |
| |||
2250 | 2251 | | |
2251 | 2252 | | |
2252 | 2253 | | |
| 2254 | + | |
2253 | 2255 | | |
2254 | 2256 | | |
2255 | 2257 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2595 | 2595 | | |
2596 | 2596 | | |
2597 | 2597 | | |
| 2598 | + | |
2598 | 2599 | | |
2599 | 2600 | | |
2600 | 2601 | | |
| |||
3642 | 3643 | | |
3643 | 3644 | | |
3644 | 3645 | | |
| 3646 | + | |
3645 | 3647 | | |
3646 | 3648 | | |
3647 | 3649 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1718 | 1718 | | |
1719 | 1719 | | |
1720 | 1720 | | |
| 1721 | + | |
1721 | 1722 | | |
1722 | 1723 | | |
1723 | 1724 | | |
| |||
2243 | 2244 | | |
2244 | 2245 | | |
2245 | 2246 | | |
| 2247 | + | |
2246 | 2248 | | |
2247 | 2249 | | |
2248 | 2250 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1718 | 1718 | | |
1719 | 1719 | | |
1720 | 1720 | | |
| 1721 | + | |
1721 | 1722 | | |
1722 | 1723 | | |
1723 | 1724 | | |
| |||
2243 | 2244 | | |
2244 | 2245 | | |
2245 | 2246 | | |
| 2247 | + | |
2246 | 2248 | | |
2247 | 2249 | | |
2248 | 2250 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4002 | 4002 | | |
4003 | 4003 | | |
4004 | 4004 | | |
| 4005 | + | |
4005 | 4006 | | |
4006 | 4007 | | |
4007 | 4008 | | |
| |||
4510 | 4511 | | |
4511 | 4512 | | |
4512 | 4513 | | |
| 4514 | + | |
4513 | 4515 | | |
4514 | 4516 | | |
4515 | 4517 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4811 | 4811 | | |
4812 | 4812 | | |
4813 | 4813 | | |
| 4814 | + | |
4814 | 4815 | | |
4815 | 4816 | | |
4816 | 4817 | | |
| |||
5849 | 5850 | | |
5850 | 5851 | | |
5851 | 5852 | | |
| 5853 | + | |
5852 | 5854 | | |
5853 | 5855 | | |
5854 | 5856 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3993 | 3993 | | |
3994 | 3994 | | |
3995 | 3995 | | |
| 3996 | + | |
3996 | 3997 | | |
3997 | 3998 | | |
3998 | 3999 | | |
| |||
4495 | 4496 | | |
4496 | 4497 | | |
4497 | 4498 | | |
| 4499 | + | |
4498 | 4500 | | |
4499 | 4501 | | |
4500 | 4502 | | |
| |||
0 commit comments