Separate scheduler rendered call from create and render (#2374)

* Separate push_component_rendered from push_component_render and push_component_update.

* Fix pr-flow.

* Make first_render more reliable.
This commit is contained in:
Kaede Hoshikawa 2022-01-23 03:04:12 +09:00 committed by GitHub
parent ef60f0943e
commit 38021e31fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 28 deletions

View File

@ -170,9 +170,6 @@ impl<COMP: BaseComponent> Runnable for UpdateRunner<COMP> {
RenderRunner {
state: self.state.clone(),
},
RenderedRunner {
state: self.state.clone(),
},
);
// Only run from the scheduler, so no need to call `scheduler::start()`
}
@ -236,6 +233,18 @@ impl<COMP: BaseComponent> Runnable for RenderRunner<COMP> {
let node = new_root.apply(&scope, m, next_sibling, ancestor);
state.node_ref.link(node);
let first_render = !state.has_rendered;
state.has_rendered = true;
scheduler::push_component_rendered(
self.state.as_ptr() as usize,
RenderedRunner {
state: self.state.clone(),
first_render,
},
first_render,
);
} else {
#[cfg(feature = "ssr")]
if let Some(tx) = state.html_sender.take() {
@ -257,9 +266,6 @@ impl<COMP: BaseComponent> Runnable for RenderRunner<COMP> {
RenderRunner {
state: shared_state.clone(),
},
RenderedRunner {
state: shared_state,
},
);
} else {
// We schedule a render after current suspension is resumed.
@ -277,9 +283,6 @@ impl<COMP: BaseComponent> Runnable for RenderRunner<COMP> {
RenderRunner {
state: shared_state.clone(),
},
RenderedRunner {
state: shared_state.clone(),
},
);
}));
@ -301,6 +304,7 @@ impl<COMP: BaseComponent> Runnable for RenderRunner<COMP> {
pub(crate) struct RenderedRunner<COMP: BaseComponent> {
pub(crate) state: Shared<Option<ComponentState<COMP>>>,
first_render: bool,
}
impl<COMP: BaseComponent> Runnable for RenderedRunner<COMP> {
@ -310,9 +314,7 @@ impl<COMP: BaseComponent> Runnable for RenderedRunner<COMP> {
crate::virtual_dom::vcomp::log_event(state.vcomp_id, "rendered");
if state.suspension.is_none() && state.parent.is_some() {
let first_render = !state.has_rendered;
state.component.rendered(&state.context, first_render);
state.has_rendered = true;
state.component.rendered(&state.context, self.first_render);
}
}
}

View File

@ -2,8 +2,7 @@
use super::{
lifecycle::{
ComponentState, CreateRunner, DestroyRunner, RenderRunner, RenderedRunner, UpdateEvent,
UpdateRunner,
ComponentState, CreateRunner, DestroyRunner, RenderRunner, UpdateEvent, UpdateRunner,
},
BaseComponent,
};
@ -244,9 +243,6 @@ impl<COMP: BaseComponent> Scope<COMP> {
RenderRunner {
state: self.state.clone(),
},
RenderedRunner {
state: self.state.clone(),
},
);
// Not guaranteed to already have the scheduler started
scheduler::start();
@ -381,9 +377,6 @@ mod feat_ssr {
RenderRunner {
state: self.state.clone(),
},
RenderedRunner {
state: self.state.clone(),
},
);
scheduler::start();

View File

@ -58,12 +58,10 @@ pub fn push(runnable: Box<dyn Runnable>) {
pub(crate) fn push_component_create(
create: impl Runnable + 'static,
first_render: impl Runnable + 'static,
first_rendered: impl Runnable + 'static,
) {
with(|s| {
s.create.push(Box::new(create));
s.render_first.push_back(Box::new(first_render));
s.rendered_first.push(Box::new(first_rendered));
});
}
@ -73,14 +71,25 @@ pub(crate) fn push_component_destroy(runnable: impl Runnable + 'static) {
}
/// Push a component render and rendered [Runnable]s to be executed
pub(crate) fn push_component_render(
component_id: usize,
render: impl Runnable + 'static,
rendered: impl Runnable + 'static,
) {
pub(crate) fn push_component_render(component_id: usize, render: impl Runnable + 'static) {
with(|s| {
s.render.schedule(component_id, Box::new(render));
s.rendered.schedule(component_id, Box::new(rendered));
});
}
pub(crate) fn push_component_rendered(
component_id: usize,
rendered: impl Runnable + 'static,
first_render: bool,
) {
with(|s| {
let rendered = Box::new(rendered);
if first_render {
s.rendered_first.push(rendered);
} else {
s.rendered.schedule(component_id, rendered);
}
});
}