Skip to content
Blog

How Brilliant hunts jank: a profiler that writes the verdict

10 min read

Jank is the easiest bug to feel and the hardest to catch. A frame lands a few milliseconds late, the canvas hitches under your cursor, and by the time you think "what was that," it's gone. No stack trace, no error, no reproduction. Just a vibe that the tool stuttered.

Brilliant renders its canvas through a native Rust wgpu engine (the story of why lives in our rust engine post), and a design tool lives or dies on that canvas staying smooth through thousands of tiny direct-manipulation gestures per session. So we built two things that refuse to let jank hide: a frame profiler that records a real session and hands back a written verdict, and a measurement culture that would rather admit "I don't know" than lie to itself with a green checkmark.

Record a session, read the verdict

The premise is simple. No DevTools, no Instruments, no on-screen HUD to eyeball. You hit start, you use the app, you hit stop, and the profiler writes a report that says, in plain language, what was slow and why.

The reason it can say why is context. Every frame in the recording knows not just how long it took but what you were doing when it happened: which gesture was live, how deep you were zoomed, what was selected, how heavy the scene was. That context is what turns a number into a sentence. A 40 ms frame is noise. A 40 ms frame that landed mid-resize, at deep zoom, on a 99-element selection is a lead.

The report doesn't stop at "this frame was slow." It decides where the time went, groups stutters into episodes instead of scattering them across single frames, and names the most expensive elements by name, so the verdict reads like a diagnosis rather than a spreadsheet: what stuttered, when, what dominated the cost, and which content was responsible. Recording costs effectively nothing when it's off and stays cheap while it's on, so profiling a real working session is a thing you actually do, not a thing you schedule.

A profiler that knows what it doesn't know

Here's where the "refuse to lie to itself" part earns its keep. A profiler is an instrument, and an instrument without error analysis is a random-number generator with confidence.

GPU timing in particular is full of traps: measurements arrive late, repeat themselves, and go bimodal under load, and a naive analysis will happily fabricate stalls that never happened or bless a drowning GPU as healthy. The profiler treats every measurement's trustworthiness as part of the measurement. When a number can't be trusted, it is excluded from the verdict rather than allowed to win it, and the report says so. When the machine is merely busy rather than stalling, the report says that too, so a healthy heavy scene never gets mistaken for a bottleneck.

The same honesty applies to how the numbers were captured. A debug build inflates everything by roughly an order of magnitude and mints phantom spikes out of thin air; we misread three field sessions before learning that lesson, so now every report carries its capture conditions and tells you when they disqualify a judgement. A verdict is only as trustworthy as the honesty about how it was captured.

Gates that a hostile machine can't flake

A profiler tells you what happened on one machine, once. To keep regressions out, we need gates in CI, and CI is a hostile place to measure milliseconds. Shared runners throttle, thermals drift, a cold run and a hot run of the same workload can move by 5x uniformly. An absolute "this must finish in N ms" gate on that hardware is a coin flip that pages you at 3 a.m.

So our performance gates never assert absolute wall-clock time. Real captured sessions are replayed through the real engine, and every gated cost is measured as a ratio against a reference workload running under the same conditions in the same run. Because the reference throttles right alongside the thing under test, the ratio stays put even as the absolute numbers swing. Costs too small to ever be felt by a human don't get to fail a build no matter how much they wobble, and measurements the machine has rendered untrustworthy are recognized and set aside rather than gated on.

The rule of thumb behind all of it: gate the shape of the cost, not the raw milliseconds, because only the shape is portable across a contended machine.

Real bytes through the real engine

The other half of not lying to yourself is refusing to test a mock. When we test the engine, we feed it the exact bytes the live application produced, captured from real sessions and replayed through the same interface the running app uses. No synthetic stand-in scene, no re-implemented protocol. If a frame renders wrong in the app, the bytes that made it wrong are the bytes under test.

The same discipline covers the profiler itself. Observing a frame must not change the frame: we prove, not assume, that a profiled render and an unprofiled render of the same scene produce identical output. And every comparison in the suite has to first prove it's comparing something real, because two renders of nothing match perfectly, and a test that can pass vacuously isn't a test. The assertion is always the strongest one the situation can actually support, and never stronger.

What it all buys

Put together, the payoff is that jank stops being a vibe. On the founder's real captured session, the profiler's verdict reads clean: p95 frame time 2.72 ms, zero jank episodes, with liquid glass correctly named as his single most expensive feature class (ablating it cut the frame's driver-side cost by 49%). That's not a benchmark we invented, it's a written verdict from a recorded session, reproduced against an independent ablation matrix.

Record a session, read the verdict, and trust it precisely as far as the honesty rules say you can. A tool that knows what it doesn't know is a tool you can actually chase jank with.