Skip to content

Commit

Permalink
feat: Performance improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
marc2332 committed Apr 3, 2024
1 parent 6cca92b commit 1082985
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 60 deletions.
16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ use_camera = ["freya/use_camera"]
hot-reload = ["freya/hot-reload"]

[patch.crates-io]
dioxus = { git = "https://github.com/DioxusLabs/dioxus", rev = "f266213618b9715e9df8c28fb51ca81e38b28055" }
dioxus-rsx = { git = "https://github.com/DioxusLabs/dioxus", rev = "f266213618b9715e9df8c28fb51ca81e38b28055" }
dioxus-core-macro = { git = "https://github.com/DioxusLabs/dioxus", rev = "f266213618b9715e9df8c28fb51ca81e38b28055" }
dioxus-hooks = { git = "https://github.com/DioxusLabs/dioxus", rev = "f266213618b9715e9df8c28fb51ca81e38b28055" }
dioxus-signals = { git = "https://github.com/DioxusLabs/dioxus", rev = "f266213618b9715e9df8c28fb51ca81e38b28055" }
dioxus-core = { git = "https://github.com/DioxusLabs/dioxus", rev = "f266213618b9715e9df8c28fb51ca81e38b28055" }
dioxus-hot-reload = { git = "https://github.com/DioxusLabs/dioxus", rev = "f266213618b9715e9df8c28fb51ca81e38b28055" }
dioxus-router = { git = "https://github.com/DioxusLabs/dioxus", rev = "f266213618b9715e9df8c28fb51ca81e38b28055" }
dioxus = { git = "https://github.com/DioxusLabs/dioxus", rev = "46b0eeb12cf2b388d29a9061b74e9470a8487679" }
dioxus-rsx = { git = "https://github.com/DioxusLabs/dioxus", rev = "46b0eeb12cf2b388d29a9061b74e9470a8487679" }
dioxus-core-macro = { git = "https://github.com/DioxusLabs/dioxus", rev = "46b0eeb12cf2b388d29a9061b74e9470a8487679" }
dioxus-hooks = { git = "https://github.com/DioxusLabs/dioxus", rev = "46b0eeb12cf2b388d29a9061b74e9470a8487679" }
dioxus-signals = { git = "https://github.com/DioxusLabs/dioxus", rev = "46b0eeb12cf2b388d29a9061b74e9470a8487679" }
dioxus-core = { git = "https://github.com/DioxusLabs/dioxus", rev = "46b0eeb12cf2b388d29a9061b74e9470a8487679" }
dioxus-hot-reload = { git = "https://github.com/DioxusLabs/dioxus", rev = "46b0eeb12cf2b388d29a9061b74e9470a8487679" }
dioxus-router = { git = "https://github.com/DioxusLabs/dioxus", rev = "46b0eeb12cf2b388d29a9061b74e9470a8487679" }

[workspace.dependencies]
freya = { path = "crates/freya", version = "0.1" }
Expand Down
10 changes: 6 additions & 4 deletions crates/common/src/paragraphs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ impl ParagraphElements {

pub fn remove_paragraph(&self, node_id: NodeId, text_id: &Uuid) {
let mut paragraphs = self.paragraphs.lock().unwrap();
let text_group = paragraphs.get_mut(text_id).unwrap();
let text_group = paragraphs.get_mut(text_id);

text_group.retain(|id| *id != node_id);
if let Some(text_group) = text_group {
text_group.retain(|id| *id != node_id);

if text_group.is_empty() {
paragraphs.remove(text_id);
if text_group.is_empty() {
paragraphs.remove(text_id);
}
}
}

Expand Down
11 changes: 4 additions & 7 deletions crates/components/src/switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,10 @@ pub fn Switch(props: SwitchProps) -> Element {
platform.set_cursor(CursorIcon::Pointer);
};

let onclick = {
let ontoggled = props.ontoggled.clone();
move |e: MouseEvent| {
e.stop_propagation();
focus.focus();
ontoggled.call(());
}
let onclick = move |e: MouseEvent| {
e.stop_propagation();
focus.focus();
props.ontoggled.call(());
};

let onkeydown = move |e: KeyboardEvent| {
Expand Down
3 changes: 0 additions & 3 deletions crates/core/src/dom/mutations_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,6 @@ impl<'a> WriteMutations for MutationsWriter<'a> {
}

fn remove_node(&mut self, id: dioxus_core::ElementId) {
let node_id = self.native_writer.state.element_to_node_id(id);
let mut dom_adapter = DioxusDOMAdapter::new_with_cache(self.native_writer.rdom);
self.layout.remove(node_id, &mut dom_adapter, true);
self.remove(id);
self.native_writer.remove_node(id);
}
Expand Down
43 changes: 19 additions & 24 deletions crates/core/src/events/events_measurer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ fn measure_dom_events(
'event: for collateral_event in collateral_events {
let mut child_node: Option<NodeId> = None;

let listeners = rdom.get_listening_sorted(&collateral_event);

// Iterate over the event nodes
for PotentialEvent {
node_id,
Expand All @@ -205,28 +203,25 @@ fn measure_dom_events(
continue;
};

// Iterate over the event listeners
for listener in &listeners {
if listener.id() == *node_id {
let valid_node = if let Some(child_node) = child_node {
is_node_parent_of(rdom, child_node, *node_id)
} else {
true
};
if rdom.is_node_listening(node_id, &collateral_event) {
let valid_node = if let Some(child_node) = child_node {
is_node_parent_of(rdom, child_node, *node_id)
} else {
true
};

if valid_node {
let mut valid_event = event.clone();
valid_event.set_name(collateral_event);
valid_events.push(PotentialEvent {
node_id: *node_id,
event: valid_event,
layer: *layer,
});

// Stack events that do not bubble up
if event.get_name().does_bubble() {
continue 'event;
}
if valid_node {
let mut valid_event = event.clone();
valid_event.set_name(collateral_event);
valid_events.push(PotentialEvent {
node_id: *node_id,
event: valid_event,
layer: *layer,
});

// Stack events that do not bubble up
if event.get_name().does_bubble() {
continue 'event;
}
}
}
Expand Down Expand Up @@ -274,7 +269,7 @@ fn emit_global_events_listeners(
) {
for global_event in global_events {
let event_name = global_event.get_name();
let listeners = fdom.rdom().get_listening_sorted(&event_name);
let listeners = fdom.rdom().get_listeners(&event_name);

for listener in listeners {
let element_id = listener.mounted_id().unwrap();
Expand Down
4 changes: 4 additions & 0 deletions crates/core/src/plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ pub enum PluginEvent<'a> {

/// After measuring the layout.
FinishedLayout(&'a Torin<NodeId>),

StartedUpdatingDOM,

FinishedUpdatingDOM,
}

/// Skeleton for Freya plugins.
Expand Down
49 changes: 48 additions & 1 deletion crates/freya/src/plugins/performance_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::time::{Duration, Instant};

use freya_core::plugins::{FreyaPlugin, PluginEvent};
use freya_engine::prelude::{
Color, FontStyle, ParagraphBuilder, ParagraphStyle, Slant, TextShadow, TextStyle, Weight, Width,
Color, FontStyle, Paint, PaintStyle, ParagraphBuilder, ParagraphStyle, Rect, Slant, TextShadow,
TextStyle, Weight, Width,
};

#[derive(Default)]
Expand All @@ -11,6 +12,10 @@ pub struct PerformanceOverlayPlugin {
started_render: Option<Instant>,
started_layout: Option<Instant>,
finished_layout: Option<Duration>,
started_dom_updates: Option<Instant>,
finished_dom_updates: Option<Duration>,
fps_historic: Vec<usize>,
max_fps: usize,
}

impl FreyaPlugin for PerformanceOverlayPlugin {
Expand All @@ -20,6 +25,10 @@ impl FreyaPlugin for PerformanceOverlayPlugin {
PluginEvent::FinishedLayout(_) => {
self.finished_layout = Some(self.started_layout.unwrap().elapsed())
}
PluginEvent::StartedUpdatingDOM => self.started_dom_updates = Some(Instant::now()),
PluginEvent::FinishedUpdatingDOM => {
self.finished_dom_updates = Some(self.started_dom_updates.unwrap().elapsed())
}
PluginEvent::BeforeRender { .. } => self.started_render = Some(Instant::now()),
PluginEvent::AfterRender {
canvas,
Expand All @@ -28,6 +37,7 @@ impl FreyaPlugin for PerformanceOverlayPlugin {
} => {
let started_render = self.started_render.take().unwrap();
let finished_layout = self.finished_layout.unwrap();
let finished_dom_updates = self.finished_dom_updates.unwrap();
let rdom = freya_dom.rdom();
let layout = freya_dom.layout();

Expand Down Expand Up @@ -57,6 +67,11 @@ impl FreyaPlugin for PerformanceOverlayPlugin {
30.0,
);

self.fps_historic.push(self.frames.len());
if self.fps_historic.len() > 70 {
self.fps_historic.remove(0);
}

// Rendering time
add_text(
&mut paragraph_builder,
Expand All @@ -71,6 +86,13 @@ impl FreyaPlugin for PerformanceOverlayPlugin {
18.0,
);

// DOM updates time
add_text(
&mut paragraph_builder,
format!("DOM Updates: {}ms \n", finished_dom_updates.as_millis()),
18.0,
);

// DOM size
add_text(
&mut paragraph_builder,
Expand All @@ -88,6 +110,31 @@ impl FreyaPlugin for PerformanceOverlayPlugin {
let mut paragraph = paragraph_builder.build();
paragraph.layout(f32::MAX);
paragraph.paint(canvas, (5.0, 0.0));

let mut paint = Paint::default();
paint.set_anti_alias(true);
paint.set_style(PaintStyle::Fill);
paint.set_color(Color::from_argb(120, 255, 255, 255));

self.max_fps = self
.max_fps
.max(self.fps_historic.iter().max().copied().unwrap_or_default());
let start_x = 5.0;
let start_y = 150.0 + self.max_fps.max(60) as f32;

canvas.draw_rect(Rect::new(5., 150., 200., start_y), &paint);

for (i, fps) in self.fps_historic.iter().enumerate() {
let mut paint = Paint::default();
paint.set_anti_alias(true);
paint.set_style(PaintStyle::Fill);
paint.set_color(Color::from_rgb(63, 255, 0));
paint.set_stroke_width(3.0);

let x = start_x + (i * 2) as f32;
let y = start_y - *fps as f32 + 2.0;
canvas.draw_circle((x, y), 2.0, &paint);
}
}
_ => {}
}
Expand Down
23 changes: 11 additions & 12 deletions crates/native-core/src/real_dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,18 +238,18 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
NodeMut::new(id, self)
}

/// Find all nodes that are listening for an event, sorted by there height in the dom progressing starting at the bottom and progressing up.
/// This can be useful to avoid creating duplicate events.
pub fn get_listening_sorted(&self, event: &EventName) -> Vec<NodeRef<V>> {
pub fn is_node_listening(&self, node_id: &NodeId, event: &EventName) -> bool {
self.nodes_listening
.get(event)
.map(|listeners| listeners.contains(node_id))
.unwrap_or_default()
}

pub fn get_listeners(&self, event: &EventName) -> Vec<NodeRef<V>> {
if let Some(nodes) = self.nodes_listening.get(event) {
let mut listening: Vec<_> = nodes
nodes
.iter()
.map(|id| (*id, self.tree_ref().height(*id).unwrap()))
.collect();
listening.sort_by(|(_, h1), (_, h2)| h1.cmp(h2).reverse());
listening
.into_iter()
.map(|(id, _)| NodeRef { id, dom: self })
.map(|id| NodeRef { id: *id, dom: self })
.collect()
} else {
Vec::new()
Expand Down Expand Up @@ -624,8 +624,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
.mark_child_changed(parent_id);
}
let children_ids = self.child_ids();
let children_ids_vec = children_ids.to_vec();
for child in children_ids_vec {
for child in children_ids {
self.dom.get_mut(child).unwrap().remove();
}
self.dom.tree_mut().remove(id);
Expand Down
5 changes: 5 additions & 0 deletions crates/renderer/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,25 @@ impl<State: 'static + Clone> App<State> {

/// Make the first build of the VirtualDOM and sync it with the RealDOM.
pub fn init_doms(&mut self) {
self.plugins.send(PluginEvent::StartedUpdatingDOM);
let scale_factor = self.window_env.window.scale_factor() as f32;
self.provide_vdom_contexts();

self.sdom.get_mut().init_dom(&mut self.vdom, scale_factor);
self.plugins.send(PluginEvent::FinishedUpdatingDOM);
}

/// Update the DOM with the mutations from the VirtualDOM.
pub fn apply_vdom_changes(&mut self) -> (bool, bool) {
self.plugins.send(PluginEvent::StartedUpdatingDOM);
let scale_factor = self.window_env.window.scale_factor() as f32;
let (repaint, relayout) = self
.sdom
.get_mut()
.render_mutations(&mut self.vdom, scale_factor);

self.plugins.send(PluginEvent::FinishedUpdatingDOM);

if repaint {
if let Some(mutations_notifier) = &self.mutations_notifier {
mutations_notifier.notify_one();
Expand Down
2 changes: 1 addition & 1 deletion crates/state/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct LayoutState {
pub position: Position,
pub content: Content,
pub node_ref: Option<NodeReference>,
pub node_id: NodeId
pub node_id: NodeId,
}

#[partial_derive_state]
Expand Down

0 comments on commit 1082985

Please sign in to comment.