DioxusLabs / DioxusLabs/blitz

Transforms lag significantly sooner than in webview

Open
#595 13 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
4.1k
Forks
203
Avg merge
8h 58m
Merged PRs (30d)
112

Description

When transforming large number of children blitz tend to lag at a way smaller amount than the webview
Platform tested: windows 11

Blitz release count: **200**

https://github.com/user-attachments/assets/d24c23e4-75d4-4ea2-bf84-57651724f822

Webview release count: **3000**

https://github.com/user-attachments/assets/3670349e-4145-43b8-8ec2-b3c47d9f8cdf

```rust
use std::collections::HashMap;

use dioxus_native::prelude::dioxus_elements::geometry::ClientPoint;
use dioxus_native::prelude::*;

const COUNT: usize = 200;

pub fn main() {
dioxus_native::launch(app);
}

fn app() -> Element {
let mut viewport = use_store(Viewport::default);
let data = use_store(Data::default);
let mut position = use_store(|| ClientPoint::zero());

let onpointermove = move |evt: Event| {
let coords = evt.client_coordinates();
viewport.write().pan(&coords, &position.peek());
position.set(coords);
};

let onwheel = move |e: Event| {
let coords = e.client_coordinates();
let delta = e.delta().strip_units().y as f32;

viewport
.write()
.onscroll(coords.x as f32, coords.y as f32, delta);
};
rsx!(
style {
{CSS}
}
div {
tabindex: "-1",
position: "absolute",
top: 0,
left: 0,
width: "100vw",
height:"100vh",
onpointermove,
onwheel,

div {
border: "1px solid black",
position: "absolute",
top: 0,
left: 0,
transform_origin: "0 0",
width: 0,
height: 0,
transform: "{viewport}",
div {
for (id, item) in data.elements().iter() {
PositionedItem{
id: id,
data: item
}
}
}
}
}
)
}

#[component]
fn PositionedItem(id: usize, data: Store) -> Element {
rsx!(
div {
z_index: id,
pointer_events: "none",
user_select: "none",
position: "absolute",
border: "1px solid black",
left: format!("{}px", data.x()),
top: format!("{}px", data.y()),
width: format!("{}px", data.width()),
height: format!("{}px", data.height()),
div {
"Placed item {id}"
}
}
)
}

#[derive(Store, Clone, PartialEq)]
struct PositinedElement {
x: f32,
y: f32,
width: f32,
height: f32,
}

#[derive(Store, PartialEq)]
struct Data {
elements: HashMap,
}

impl Default for Data {
fn default() -> Self {
Self {
elements: (0..COUNT)
.map(|i| {
(
i,
PositinedElement {
x: i as f32 * 30.0,
y: i as f32 * 20.0,
width: 60.0 + ((i * 37 + 11) % 100) as f32 * 0.8,
height: 60.0 + ((i * 53 + 7) % 100) as f32 * 0.8,
},
)
})
.collect(),
}
}
}

#[derive(Store, Debug, Clone, PartialEq)]
struct Viewport {
pan_x: f32,
pan_y: f32,
zoom: f32,
}

impl std::fmt::Display for Viewport {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"translate({}px, {}px) scale({})",
self.pan_x, self.pan_y, self.zoom
)
}
}

impl Default for Viewport {
fn default() -> Self {
Self {
pan_x: Default::default(),
pan_y: Default::default(),
zoom: 1.0,
}
}
}

impl Viewport {
fn pan(&mut self, screen: &ClientPoint, last: &ClientPoint) {
let dx = screen.x - last.x;
let dy = screen.y - last.y;
self.pan_x += dx as f32;
self.pan_y += dy as f32;
}
pub fn onscroll(&mut self, sx: f32, sy: f32, delta: f32) {
let factor = (1.0 + delta).clamp(0.8, 1.2);

let new_zoom = (self.zoom * factor).clamp(0.05, 50.0);

let wx = (sx - self.pan_x) / self.zoom;
let wy = (sy - self.pan_y) / self.zoom;

self.pan_x = sx - wx * new_zoom;
self.pan_y = sy - wy * new_zoom;
self.zoom = new_zoom;
}
}

const CSS: &str = r#"
* {
box-sizing: border-box;
}

html,
body,
main {
width: 100vw;
height: 100vh;
margin: 0;
}
"#;
```

Contributor guide

Open the contributing guide

Research direction

Start by running the supplied Rust reproduction on Windows 11 and compare how many transformed children remain responsive in Blitz versus the webview. Investigate the transform and rendering path exposed by this example; done means large child counts no longer make Blitz lag substantially earlier than the reported webview baseline.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
frontend, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.