Commit e705e8d
Cache parent lookups during event dispatch (#56853)
Summary:
Pull Request resolved: #56853
The W3C event-dispatch pipeline (gated on `enableNativeEventTargetEventDispatching`) walks the parent chain of the dispatched target on every event: once in `EventTarget.getEventPath` for the capture/bubble path, plus up to two additional walks in the responder system for touch/scroll/selection events. Each `parentNode` read is a JSI hop into C++ that re-walks the family chain in the current shadow-tree revision, so on event-heavy screens (e.g., a list firing many `onLayout` events during mount) the per-event walk cost adds up.
This change adds a per-instance parent cache that all event-dispatch consumers share. RN host trees are append-only and the shadow tree is stable during dispatch, so once a node is reachable from the dispatch path its parent is permanently stable from that pipeline's point of view. The cache stores the resolved parent in a symbol-keyed slot on the first lookup; subsequent lookups (within the same dispatch and across future dispatches on the same tree) collapse to a property load.
- Add `getEventTargetParent(target)` in `EventTargetInternals` (plus the cache slot and a sentinel for cached nulls).
- Route `EventTarget.getEventPath` through the new utility.
- Route the `parentElement` walks in `ReactNativeResponder` (`getLowestCommonAncestor`, `negotiateResponder` path build, and the `skipSelf` step) through the same utility, with an `instanceof ReadOnlyElement` filter so the responder's element-only invariant is preserved.
- Leave the `parentNode` getter on `ReadOnlyNode` untouched — user-visible reads still take the canonical JSI path and detached-node reads continue to return `null`.
- Add two stable-tree scenarios to `EventDispatching-benchmark-itest.js` (`beforeAll` mounts once, the benchmarked function dispatches per iteration) so the cache win is measurable and any regression in the rebuild-per-iter scenarios is also visible.
## Benchmark results
Ran `yarn fantom EventDispatching-benchmark --benchmarks` from `xplat/js/react-native-github/`, comparing the cache disabled (utility short-circuited to the canonical getter) against the cache enabled. Numbers below are p50 latency; both runs use Hermes-bytecode optimized mode (the default for `*-benchmark-itest.js`).
New stable-tree scenarios with the new pipeline (`enableNativeEventTargetEventDispatching` ON):
| Scenario (depth 50, stable tree) | Cache OFF | Cache ON | Improvement |
| ------------------------------------------------ | --------- | -------- | ------------------- |
| dispatch event, bubbling, handlers on ancestors | 0.271 ms | 0.165 ms | 39% faster (1.64×) |
| dispatch event, no handlers on ancestors | 0.265 ms | 0.161 ms | 39% faster (1.65×) |
Pre-existing rebuild-per-iter scenarios with the new pipeline (no measurable change — cache is empty on each iteration):
| Scenario (flag ON) | Cache OFF | Cache ON | Δ |
| ------------------------------------- | --------- | -------- | - |
| flat (1 handler) | 0.042 ms | 0.042 ms | — |
| nested 10 deep (bubbling) | 0.105 ms | 0.106 ms | — |
| nested 50 deep (bubbling) | 0.378 ms | 0.381 ms | — |
| nested 10 deep (no handlers) | 0.103 ms | 0.104 ms | — |
| stopPropagation, nested 10 deep | 0.089 ms | 0.091 ms | — |
| render + dispatch, flat | 0.082 ms | 0.083 ms | — |
Legacy pipeline (`enableNativeEventTargetEventDispatching` OFF) was unchanged across both runs, confirming the cache change does not leak outside the new pipeline.
Changelog: [Internal]
Reviewed By: andrewdacenko
Differential Revision: D105337953
fbshipit-source-id: cd157aaa34049906de00566a901a87f0e447b6441 parent 3b9c581 commit e705e8d
4 files changed
Lines changed: 106 additions & 6 deletions
File tree
- packages/react-native/src/private
- renderer
- core/__tests__
- events
- webapis/dom/events
- internals
Lines changed: 61 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
261 | 261 | | |
262 | 262 | | |
263 | 263 | | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
264 | 325 | | |
265 | 326 | | |
Lines changed: 22 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
| |||
78 | 79 | | |
79 | 80 | | |
80 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
81 | 99 | | |
82 | 100 | | |
83 | 101 | | |
| |||
95 | 113 | | |
96 | 114 | | |
97 | 115 | | |
98 | | - | |
| 116 | + | |
99 | 117 | | |
100 | 118 | | |
101 | 119 | | |
102 | 120 | | |
103 | | - | |
| 121 | + | |
104 | 122 | | |
105 | 123 | | |
106 | 124 | | |
| |||
265 | 283 | | |
266 | 284 | | |
267 | 285 | | |
268 | | - | |
| 286 | + | |
269 | 287 | | |
270 | 288 | | |
271 | 289 | | |
| |||
276 | 294 | | |
277 | 295 | | |
278 | 296 | | |
279 | | - | |
| 297 | + | |
280 | 298 | | |
281 | 299 | | |
282 | 300 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
341 | 342 | | |
342 | 343 | | |
343 | 344 | | |
344 | | - | |
345 | | - | |
| 345 | + | |
346 | 346 | | |
347 | 347 | | |
348 | 348 | | |
| |||
Lines changed: 21 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
50 | 71 | | |
51 | 72 | | |
52 | 73 | | |
| |||
0 commit comments