Skip to content

perf: eliminate O(N^2) DomSlot chain traversal in BList#4090

Closed
Madoshakalaka wants to merge 1 commit intomasterfrom
perf/blist-O1-domslot-resolution
Closed

perf: eliminate O(N^2) DomSlot chain traversal in BList#4090
Madoshakalaka wants to merge 1 commit intomasterfrom
perf/blist-O1-domslot-resolution

Conversation

@Madoshakalaka
Copy link
Copy Markdown
Member

This adds parent-link notification to DynamicDomSlot: when reassign is called and a parent is set, the resolved position is eagerly propagated.

BList now maintains per-child DynamicDomSlots (rev_child_slots) that are always eagerly resolved to concrete DOM nodes.

During reconciliation, the NodeWriter uses child_slot.to_position() (constant depth) instead of chaining through own_position

Component children get a parent link from own_position to their child_slot, so independent re-renders automatically keep the slot in sync

Checklist

  • I have reviewed my own code
  • I have added tests

Add parent-link notification to DynamicDomSlot and per-child position
slots to BList. When a component's own_position is reassigned, the
parent link eagerly resolves and propagates the concrete Node to the
BList's child_slot. The NodeWriter then uses child_slot.to_position()
(depth 1) instead of chaining through own_position (depth O(N)).

This bounds DomSlot chain depth to O(1) per hop, reducing total
reconciliation cost from O(N^2) to O(N) for lists of N children.
@Madoshakalaka Madoshakalaka added performance A-yew Area: The main yew crate labels Mar 29, 2026
@github-actions
Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 3e535fc):

https://yew-rs-api--pr4090-perf-blist-o1-domslo-lfoojkz9.web.app

(expires Sun, 05 Apr 2026 16:02:30 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@github-actions
Copy link
Copy Markdown

Benchmark - core

Yew Master

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  4.003 ns      │ 4.052 ns      │ 4.005 ns      │ 4.007 ns      │ 100     │ 1000000000

Pull Request

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  4.007 ns      │ 4.055 ns      │ 4.01 ns       │ 4.011 ns      │ 100     │ 1000000000

@github-actions
Copy link
Copy Markdown

Size Comparison

Details
examples master (KB) pull request (KB) diff (KB) diff (%)
async_clock 100.857 105.835 +4.978 +4.935%
boids 168.449 173.432 +4.982 +2.958%
communication_child_to_parent 94.074 99.050 +4.976 +5.289%
communication_grandchild_with_grandparent 105.915 110.922 +5.007 +4.727%
communication_grandparent_to_grandchild 102.256 107.236 +4.980 +4.871%
communication_parent_to_child 91.485 96.461 +4.976 +5.439%
contexts 105.974 110.997 +5.023 +4.740%
counter 86.797 91.771 +4.974 +5.730%
counter_functional 88.832 93.763 +4.931 +5.551%
dyn_create_destroy_apps 90.711 95.735 +5.024 +5.539%
file_upload 99.812 104.789 +4.978 +4.987%
function_delayed_input 94.814 99.738 +4.924 +5.193%
function_memory_game 173.664 178.628 +4.964 +2.858%
function_router 395.766 400.881 +5.115 +1.292%
function_todomvc 164.958 169.902 +4.944 +2.997%
futures 235.550 240.523 +4.974 +2.111%
game_of_life 105.098 109.997 +4.899 +4.662%
immutable 259.622 267.979 +8.357 +3.219%
inner_html 81.340 86.320 +4.980 +6.123%
js_callback 109.961 114.929 +4.968 +4.518%
keyed_list 180.405 185.385 +4.979 +2.760%
mount_point 84.713 89.688 +4.976 +5.873%
nested_list 113.662 118.576 +4.914 +4.323%
node_refs 92.085 97.061 +4.976 +5.403%
password_strength 1718.926 1723.887 +4.961 +0.289%
portals 93.557 98.553 +4.996 +5.340%
router 366.408 371.453 +5.045 +1.377%
suspense 113.961 118.954 +4.993 +4.381%
timer 88.942 93.940 +4.998 +5.619%
timer_functional 99.368 104.357 +4.989 +5.021%
todomvc 142.660 147.557 +4.896 +3.432%
two_apps 86.710 91.684 +4.974 +5.736%
web_worker_fib 136.456 141.440 +4.984 +3.653%
web_worker_prime 187.638 192.622 +4.984 +2.656%
webgl 83.486 88.418 +4.932 +5.907%

⚠️ The following examples have changed their size significantly:

examples master (KB) pull request (KB) diff (KB) diff (%)
async_clock 100.857 105.835 +4.978 +4.935%
boids 168.449 173.432 +4.982 +2.958%
communication_child_to_parent 94.074 99.050 +4.976 +5.289%
communication_grandchild_with_grandparent 105.915 110.922 +5.007 +4.727%
communication_grandparent_to_grandchild 102.256 107.236 +4.980 +4.871%
communication_parent_to_child 91.485 96.461 +4.976 +5.439%
contexts 105.974 110.997 +5.023 +4.740%
counter 86.797 91.771 +4.974 +5.730%
counter_functional 88.832 93.763 +4.931 +5.551%
dyn_create_destroy_apps 90.711 95.735 +5.024 +5.539%
file_upload 99.812 104.789 +4.978 +4.987%
function_delayed_input 94.814 99.738 +4.924 +5.193%
function_memory_game 173.664 178.628 +4.964 +2.858%
function_router 395.766 400.881 +5.115 +1.292%
function_todomvc 164.958 169.902 +4.944 +2.997%
futures 235.550 240.523 +4.974 +2.111%
game_of_life 105.098 109.997 +4.899 +4.662%
immutable 259.622 267.979 +8.357 +3.219%
inner_html 81.340 86.320 +4.980 +6.123%
js_callback 109.961 114.929 +4.968 +4.518%
keyed_list 180.405 185.385 +4.979 +2.760%
mount_point 84.713 89.688 +4.976 +5.873%
nested_list 113.662 118.576 +4.914 +4.323%
node_refs 92.085 97.061 +4.976 +5.403%
portals 93.557 98.553 +4.996 +5.340%
router 366.408 371.453 +5.045 +1.377%
suspense 113.961 118.954 +4.993 +4.381%
timer 88.942 93.940 +4.998 +5.619%
timer_functional 99.368 104.357 +4.989 +5.021%
todomvc 142.660 147.557 +4.896 +3.432%
two_apps 86.710 91.684 +4.974 +5.736%
web_worker_fib 136.456 141.440 +4.984 +3.653%
web_worker_prime 187.638 192.622 +4.984 +2.656%
webgl 83.486 88.418 +4.932 +5.907%

@github-actions
Copy link
Copy Markdown

Benchmark - SSR

Yew Master

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 310.955 312.715 311.419 0.508
Hello World 10 478.031 480.724 479.315 1.013
Function Router 10 40874.736 46277.227 44175.804 1940.917
Concurrent Task 10 1006.158 1007.914 1007.167 0.592
Many Providers 10 1099.160 1130.203 1108.735 10.572

Pull Request

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 311.079 337.708 313.906 8.365
Hello World 10 480.655 517.427 492.833 12.725
Function Router 10 35316.814 46501.280 43385.278 3546.038
Concurrent Task 10 1006.299 1007.878 1007.211 0.550
Many Providers 10 1096.304 1145.368 1109.474 16.074

@Madoshakalaka
Copy link
Copy Markdown
Member Author

Nvm, cannot make it work lol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-yew Area: The main yew crate performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant