diff --git a/packages/web/NOTES.md b/packages/web/NOTES.md deleted file mode 100644 index 932bbf60d..000000000 --- a/packages/web/NOTES.md +++ /dev/null @@ -1,35 +0,0 @@ - -// ## RequestAnimationFrame and RequestIdleCallback -// ------------------------------------------------ -// React implements "jank free rendering" by deliberately not blocking the browser's main thread. For large diffs, long -// running work, and integration with things like React-Three-Fiber, it's extremely important to avoid blocking the -// main thread. -// -// React solves this problem by breaking up the rendering process into a "diff" phase and a "render" phase. In Dioxus, -// the diff phase is non-blocking, using "work_with_deadline" to allow the browser to process other events. When the diff phase -// is finally complete, the VirtualDOM will return a set of "Mutations" for this crate to apply. -// -// Here, we schedule the "diff" phase during the browser's idle period, achieved by calling RequestIdleCallback and then -// setting a timeout from the that completes when the idleperiod is over. Then, we call requestAnimationFrame -// -// From Google's guide on rAF and rIC: -// ----------------------------------- -// -// If the callback is fired at the end of the frame, it will be scheduled to go after the current frame has been committed, -// which means that style changes will have been applied, and, importantly, layout calculated. If we make DOM changes inside -// of the idle callback, those layout calculations will be invalidated. If there are any kind of layout reads in the next -// frame, e.g. getBoundingClientRect, clientWidth, etc, the browser will have to perform a Forced Synchronous Layout, -// which is a potential performance bottleneck. -// -// Another reason not trigger DOM changes in the idle callback is that the time impact of changing the DOM is unpredictable, -// and as such we could easily go past the deadline the browser provided. -// -// The best practice is to only make DOM changes inside of a requestAnimationFrame callback, since it is scheduled by the -// browser with that type of work in mind. That means that our code will need to use a document fragment, which can then -// be appended in the next requestAnimationFrame callback. If you are using a VDOM library, you would use requestIdleCallback -// to make changes, but you would apply the DOM patches in the next requestAnimationFrame callback, not the idle callback. -// -// Essentially: -// ------------ -// - Do the VDOM work during the idlecallback -// - Do DOM work in the next requestAnimationFrame callback diff --git a/packages/web/examples/README.md b/packages/web/examples/README.md deleted file mode 100644 index faa322df3..000000000 --- a/packages/web/examples/README.md +++ /dev/null @@ -1,10 +0,0 @@ -Examples -======== - -# Hydrate - -- `hydrate` show hydrate - -# Async - -- `timeout_count` button to add count and show count in the future diff --git a/packages/web/examples/hydrate.rs b/packages/web/examples/hydrate.rs deleted file mode 100644 index 1cd0d9ae3..000000000 --- a/packages/web/examples/hydrate.rs +++ /dev/null @@ -1,57 +0,0 @@ -use dioxus::prelude::*; -use dioxus_web::Config; -use web_sys::window; - -fn app() -> Element { - rsx! { - div { h1 { "thing 1" } } - div { h2 { "thing 2" } } - div { - h2 { "thing 2" } - "asd" - "asd" - Bapp {} - } - {(0..10).map(|f| rsx! { - div { - "thing {f}" - } - })} - } -} - -#[allow(non_snake_case)] -fn Bapp() -> Element { - rsx! { - div { h1 { "thing 1" } } - div { h2 { "thing 2" } } - div { - h2 { "thing 2" } - "asd" - "asd" - } - } -} - -fn main() { - console_error_panic_hook::set_once(); - tracing_wasm::set_as_global_default(); - - let mut dom = VirtualDom::new(app); - dom.rebuild(&mut dioxus_core::NoOpMutations); - - let pre = dioxus_ssr::pre_render(&dom); - tracing::trace!("{}", pre); - - // set the inner content of main to the pre-rendered content - window() - .unwrap() - .document() - .unwrap() - .get_element_by_id("main") - .unwrap() - .set_inner_html(&pre); - - // now rehydrate - dioxus_web::launch::launch(app, vec![], Config::new().hydrate(true)); -} diff --git a/packages/web/examples/timeout_count.rs b/packages/web/examples/timeout_count.rs deleted file mode 100644 index 57736f19e..000000000 --- a/packages/web/examples/timeout_count.rs +++ /dev/null @@ -1,34 +0,0 @@ -// https://jakelazaroff.com/words/were-react-hooks-a-mistake/ -use dioxus::prelude::*; - -fn main() { - dioxus_web::launch::launch(app, vec![], Default::default()); -} - -fn app() -> Element { - let mut count = use_signal(|| 0); - let mut started = use_signal(|| false); - - let mut start = move || { - if !started() { - let alert = move || gloo_dialogs::alert(&format!("Your score was {count}!",)); - gloo_timers::callback::Timeout::new(5_000, alert).forget(); - } - started.set(true); // this cannot be done inside condition or infinite loop - }; - - rsx! { - button { - onclick: move |_event| { - start(); - count += 1; - }, - - if started() { - "Current score: {count}" - } else { - "Start" - } - } - } -} diff --git a/packages/web/ric_raf/README.md b/packages/web/ric_raf/README.md deleted file mode 100644 index b101360f7..000000000 --- a/packages/web/ric_raf/README.md +++ /dev/null @@ -1,3 +0,0 @@ -requestIdleCallback and requestAnimationFrame implementation - -These currently actually slow down our DOM patching and thus are temporarily removed. Technically we can schedule around rIC and rAF but choose not to. diff --git a/packages/web/ric_raf/ric_raf.rs b/packages/web/ric_raf/ric_raf.rs deleted file mode 100644 index 89819fff0..000000000 --- a/packages/web/ric_raf/ric_raf.rs +++ /dev/null @@ -1,80 +0,0 @@ -//! This module provides some utilities around scheduling tasks on the main thread of the browser. -//! -//! The ultimate goal here is to not block the main thread during animation frames, so our animations don't result in "jank". -//! -//! Hence, this module provides Dioxus "Jank Free Rendering" on the web. -//! -//! Because RIC doesn't work on Safari, we polyfill using the "ricpolyfill.js" file and use some basic detection to see -//! if RIC is available. - -use futures_util::StreamExt; -use gloo_timers::future::TimeoutFuture; -use js_sys::Function; -use wasm_bindgen::{prelude::Closure, JsCast, JsValue}; -use web_sys::{window, Window}; - -pub(crate) struct RafLoop { - window: Window, - ric_receiver: futures_channel::mpsc::UnboundedReceiver, - raf_receiver: futures_channel::mpsc::UnboundedReceiver<()>, - ric_closure: Closure, - raf_closure: Closure, -} - -impl RafLoop { - pub fn new() -> Self { - let (raf_sender, raf_receiver) = futures_channel::mpsc::unbounded(); - - let raf_closure: Closure = Closure::wrap(Box::new(move |_v: JsValue| { - raf_sender.unbounded_send(()).unwrap() - })); - - let (ric_sender, ric_receiver) = futures_channel::mpsc::unbounded(); - - let has_idle_callback = { - let bo = window().unwrap().dyn_into::().unwrap(); - bo.has_own_property(&JsValue::from_str("requestIdleCallback")) - }; - let ric_closure: Closure = Closure::wrap(Box::new(move |v: JsValue| { - let time_remaining = if has_idle_callback { - if let Ok(deadline) = v.dyn_into::() { - deadline.time_remaining() as u32 - } else { - 10 - } - } else { - 10 - }; - - ric_sender.unbounded_send(time_remaining).unwrap() - })); - - // execute the polyfill for safari - Function::new_no_args(include_str!("./ricpolyfill.js")) - .call0(&JsValue::NULL) - .unwrap(); - - let window = web_sys::window().unwrap(); - - Self { - window, - raf_receiver, - raf_closure, - ric_receiver, - ric_closure, - } - } - /// waits for some idle time and returns a timeout future that expires after the idle time has passed - pub async fn wait_for_idle_time(&mut self) -> TimeoutFuture { - let ric_fn = self.ric_closure.as_ref().dyn_ref::().unwrap(); - let _cb_id: u32 = self.window.request_idle_callback(ric_fn).unwrap(); - let deadline = self.ric_receiver.next().await.unwrap(); - TimeoutFuture::new(deadline) - } - - pub async fn wait_for_raf(&mut self) { - let raf_fn = self.raf_closure.as_ref().dyn_ref::().unwrap(); - let _id: i32 = self.window.request_animation_frame(raf_fn).unwrap(); - self.raf_receiver.next().await.unwrap(); - } -} diff --git a/packages/web/ric_raf/ricpolyfill.js b/packages/web/ric_raf/ricpolyfill.js deleted file mode 100644 index cd114f4ca..000000000 --- a/packages/web/ric_raf/ricpolyfill.js +++ /dev/null @@ -1,28 +0,0 @@ -const requestIdleCallback = - (typeof self !== 'undefined' && - self.requestIdleCallback && - self.requestIdleCallback.bind(window)) || - function (cb) { - const start = Date.now(); - return setTimeout(() => { - cb({ - didTimeout: false, - timeRemaining: function () { - return Math.max(0, 50 - (Date.now() - start)); - }, - }); - }, 1); - }; - -const cancelIdleCallback = - (typeof self !== 'undefined' && - self.cancelIdleCallback && - self.cancelIdleCallback.bind(window)) || - function (id) { - return clearTimeout(id); - }; - -if (typeof window !== 'undefined') { - window.requestIdleCallback = requestIdleCallback; - window.cancelIdleCallback = cancelIdleCallback; -} diff --git a/packages/web/tests/hydrate.rs b/packages/web/tests/hydrate.rs deleted file mode 100644 index a409a4a75..000000000 --- a/packages/web/tests/hydrate.rs +++ /dev/null @@ -1,56 +0,0 @@ -use dioxus::prelude::*; -use dioxus_web::Config; -use wasm_bindgen_test::wasm_bindgen_test; -use web_sys::window; - -wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); - -#[test] -fn makes_tree() { - fn app() -> Element { - rsx! { - div { - div { h1 {} } - div { h2 {} } - } - } - } - - let mut dom = VirtualDom::new(app); - let muts = dom.rebuild_to_vec(); - - dbg!(muts.edits); -} - -#[wasm_bindgen_test] -fn rehydrates() { - fn app() -> Element { - rsx! { - div { - div { h1 { "h1" } } - div { h2 { "h2" } } - button { - onclick: move |_| { - println!("clicked"); - }, - "listener test" - } - {false.then(|| rsx! { "hello" })} - } - } - } - - let mut dom = VirtualDom::new(app); - dom.rebuild(&mut dioxus_core::NoOpMutations); - let out = dioxus_ssr::render(&dom); - - window() - .unwrap() - .document() - .unwrap() - .body() - .unwrap() - .set_inner_html(&format!("
{out}
")); - - dioxus_web::launch::launch_cfg(app, Config::new().hydrate(true)); -}