Skip to content

Conversation

@Madoshakalaka
Copy link
Member

we've been having flakey hydration tests for quite a few weeks.

Assertion failures look like:

  left: "<div><!--<[...Comp]>--><div>12345</div><script type=\"application/x-yew-comp-state\">...</script><!--</[...Comp]>--></div>"
  right: "<div><div>12345</div></div>"

We see failure modes show different stages of incomplete hydration too

  • Sometimes only inner components don't complete (Comp markers remain)
  • Sometimes even outer component hydration doesn't complete (all markers remain)

This happens because client side decode is async:

  async fn decode_base64(s: &str) -> Result<Vec<u8>, JsValue> {
     let fetch_promise = window().fetch_with_str(s);  // ← Uses browser fetch API

     let content_promise = JsFuture::from(fetch_promise)
         .await
         .and_then(|m| m.dyn_into::<web_sys::Response>())
         .and_then(|m| m.array_buffer())?;

     let content_array = JsFuture::from(content_promise)
         .await
         .as_ref()
         .map(Uint8Array::new)?;

     Ok(content_array.to_vec())
 }

It's a design choice:

#2650 (comment)

The use_prepared_state and use_transitive_state hydration tests were
flaky due to the async nature of base64 decoding via fetch API for
data: URLs. The 100ms timeout was sometimes insufficient on CI runners
under load.

Increase timeouts from 100ms to 200ms to provide more headroom for the
async hydration chain to complete.
@Madoshakalaka Madoshakalaka marked this pull request as ready for review January 8, 2026 07:08
@github-actions
Copy link

github-actions bot commented Jan 8, 2026

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

https://yew-rs-api--pr3973-fix-flaky-hydration-xjb6l9oi.web.app

(expires Thu, 15 Jan 2026 07:09:46 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@github-actions
Copy link

github-actions bot commented Jan 8, 2026

Benchmark - core

Yew Master

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.462 ns      │ 3.84 ns       │ 3.705 ns      │ 3.398 ns      │ 100     │ 1000000000

Pull Request

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  3.726 ns      │ 4.08 ns       │ 3.731 ns      │ 3.736 ns      │ 100     │ 1000000000

@github-actions
Copy link

github-actions bot commented Jan 8, 2026

Benchmark - SSR

Yew Master

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 290.861 293.055 291.358 0.804
Hello World 10 508.967 519.739 511.250 3.307
Function Router 10 1710.906 1729.588 1719.772 6.212
Concurrent Task 10 1005.767 1007.351 1006.583 0.509
Many Providers 10 1102.832 1150.264 1119.780 15.299

Pull Request

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 290.867 293.148 291.407 0.678
Hello World 10 503.684 554.924 512.996 15.237
Function Router 10 1675.987 1701.277 1687.888 9.030
Concurrent Task 10 1005.115 1007.539 1006.340 0.795
Many Providers 10 1107.025 1175.180 1130.156 22.926

@github-actions
Copy link

github-actions bot commented Jan 8, 2026

Size Comparison

Details
examples master (KB) pull request (KB) diff (KB) diff (%)
async_clock 98.184 98.184 0 0.000%
boids 167.706 167.706 0 0.000%
communication_child_to_parent 91.397 91.397 0 0.000%
communication_grandchild_with_grandparent 102.510 102.510 0 0.000%
communication_grandparent_to_grandchild 98.877 98.877 0 0.000%
communication_parent_to_child 88.759 88.759 0 0.000%
contexts 104.046 104.046 0 0.000%
counter 85.430 85.430 0 0.000%
counter_functional 85.794 85.794 0 0.000%
dyn_create_destroy_apps 88.521 88.521 0 0.000%
file_upload 98.022 98.022 0 0.000%
function_delayed_input 91.317 91.317 0 0.000%
function_memory_game 169.858 169.858 0 0.000%
function_router 327.898 327.898 0 0.000%
function_todomvc 161.445 161.445 0 0.000%
futures 234.383 234.383 0 0.000%
game_of_life 103.747 103.747 0 0.000%
immutable 245.762 245.762 0 0.000%
inner_html 79.913 79.913 0 0.000%
js_callback 107.816 107.816 0 0.000%
keyed_list 179.127 179.127 0 0.000%
mount_point 83.130 83.130 0 0.000%
nested_list 112.702 112.702 0 0.000%
node_refs 90.774 90.774 0 0.000%
password_strength 1738.872 1738.872 0 0.000%
portals 92.269 92.269 0 0.000%
router 301.011 301.011 0 0.000%
suspense 111.770 111.770 0 0.000%
timer 87.980 87.980 0 0.000%
timer_functional 96.062 96.062 0 0.000%
todomvc 141.425 141.425 0 0.000%
two_apps 85.293 85.293 0 0.000%
web_worker_fib 133.415 133.415 0 0.000%
web_worker_prime 184.984 184.984 0 0.000%
webgl 82.474 82.474 0 0.000%

✅ None of the examples has changed their size significantly.

@Madoshakalaka Madoshakalaka merged commit 0ec71a3 into master Jan 10, 2026
26 checks passed
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.

2 participants