Building Charton: A WGPU-Powered General Visualization Library. Just pushed 50k points at 60 FPS on integrated graphics, but hit a WASM bottleneck. Any advice?
Hey Reddit!
I’ve been working on charton, a general-purpose visualization library for the web. In my previous iteration, I got basic interactive sine waves running via the GPU, but the architecture was still hurting from heavy heap allocations. After refactoring the JS/WASM boundary into a stateful, zero-allocation setup, I finally managed to render a 50,000-point Lorenz Attractor dynamically at a locked 60 FPS using WGPU.
Here is a quick look at how the data updates are handled now:
src/lib.rs:
pub async fn update_and_render(&mut self, xs: &[f64], ys: &[f64], colors: &[f64]) -> Result<(), JsValue> {
self.dataset.update_column_f64("x", xs)?; // In-place memcpy without allocation
Chart::build(self.dataset.clone())?.mark_point().render_to_canvas(&self.canvas_id).await?
}
index.html:
const app = new LiveChartApp("chart-canvas", TOTAL_POINTS);
// Inside the requestAnimationFrame loop:
await app.update_and_render(xs, ys, colors);
I'm currently stress-testing this on a budget laptop setup: a 13th Gen Intel Core i5-13420H (2.10 GHz) with integrated Intel UHD Graphics (128 MB). My GPU utilization hovers around 70%, but because WASM runs single-threaded here, one CPU core is completely maxed out feeding the render pipeline. Since charton is meant to be a general-purpose visualization library, I can't rely on equation-specific math hacks. Do you have any recommendations for generic data-streaming patterns or memory layouts across the WASM boundary to relieve the CPU?
Moving forward, I'm planning to use this engine to create equation-driven short videos and data art animations. I’d love to hear your thoughts—what kind of interesting use cases, large datasets, or simulation scenarios would you love to see a high-performance library like this tackle next?