{
"path": "/posts/man-vs-vibes",
"site": "at://did:plc:pans3xjam4khj7y54dx7gtfg/site.standard.publication/3mdqevmg6w32c",
"tags": [
"rust",
"WebGL",
"performance",
"WASM"
],
"$type": "site.standard.document",
"title": "Man vs Vibes",
"description": "Got nerd sniped into missing a workout, and improving the performace of rendering 500k rectangles by 10x.",
"publishedAt": "2025-08-22T18:55:13.000Z",
"textContent": "Yesterday I got nerd sniped into missing a workout.\n\n{{< video fullWidth=true src=\"/rectangles.webm\" type=\"video/webm\" >}}\n\n<a href=\"/frankenpenguin/?rectangles=200000\" target=\"_blank\" rel=\"noopener noreferrer\">Frankenpenguin</a> | <a href=\"https://github.com/tauseefk/frankenpenguin\" target=\"_blank\" rel=\"noopener noreferrer\">Repository</a>\n\n[2:30 PM] I discovered a blog post about vibe coded performance benchmarks for drawing a large number of rectangles on the HTML canvas.\nIt was an interesting read and I was nodding along until I saw that all the Typescript benchmarks were better than the Rust ones. That can't be right?\n\n[3:00 PM] My hunch was that most of the time was spent crossing the boundary between Rust and Javascript. This is something I've been burned by in the past.\n\n[3:30 PM] I decoupled the work scheduling from the sync compute and rendering [1].\nDeleted a few lines of code that were creating the render loop and recursively calling it from the request_animation_frame. And then moved the scheduling to Javascript.\n\nBEFORE\n\nAFTER\n\n[3:45 PM] I run the benchmarks. Hmmmm, it's 2x faster, not bad. I was mistakenly comparing the updated Rust + WebGL implementation to the TS + WebGL version.\n\n[4:00 PM] The train is unusually late.\n\n[4:38 PM] I get to the gym, but the person turns me away as I'm too late [2].\n\n[5:21 PM] I push the repository to GitHub.\n\n[This morning] I realize that I was comparing the wrong benchmarks and the diff resulted in a 10x bump in perf.\n\nAside 1:\nTo schedule async work in the browser you can pass a callback to the requestAnimationFrame API.\nAs Rust doesn't ship with a runtime, scheduling work requires using the closest one avaiable. In the browser it ends up being... the browser. So you have to use a crate that would provide the bindings to the requestAnimationFrame API.\n\nAside 2:\nI ended with playing Table Tennis afterwards so it's all good.",
"canonicalUrl": "https://afloat.boats/posts/man-vs-vibes"
}