Rubicon
Experiment 001 / Rendering & performance
Fluffy blobs.
Each HTML blob owns an SVG filter and noise seed. Noise, blur and displacement are evaluated when its source repaints.
Rendering performance
Worst frame interval
rAF scheduling estimatePeaks / 250ms · dashed line = 16.7ms reference (60Hz)
Saved tests 0 this page session
Every completed test stays here until you clear it or reload. Bars share a 0–16.7ms scale. Lower intervals mean faster callback cadence; settings and workload must match for a fair comparison.
Run a resize or current-scene test to start comparing. Manual recordings are saved here too.
How we measure / what the numbers mean
- Worst frame interval (ms)
- The longest gap between actual requestAnimationFrame callback executions in the last 5 seconds. We timestamp with performance.now(). A spike reveals a main-thread scheduling stall, not the exact GPU render time.
- Timeline
- The last 10 seconds, split into 250ms buckets. Each bar shows the largest callback gap ending in that bucket. The scale expands for large stalls; empty buckets mean no samples. The dashed 16.7ms line is a 60Hz reference, not detection of your monitor’s refresh rate. A 120Hz cadence is roughly 8.3ms.
- p95 / worst in saved tests
- p95 is the interval at or below which 95% of recorded callback gaps fall; worst is the single longest gap. Lower usually means smoother main-thread cadence. Rare stalls can be absent from p95, so compare both. These are whole intervals, not extra delay above a frame budget.
- Baseline / scene / Δ p95
- Baseline is this page with zero blobs; scene includes the configured instances. Δ is scene p95 minus that run’s baseline p95, in milliseconds. It is a comparison, not an isolated measurement of component render cost. Saved rows keep their original count, size, parameters and workload.
- Duration and sampling
- Each paired pass settles for 1 second and records for about 3 seconds. The finish waits for a final rendering opportunity, so actual duration can be longer and is saved with the run. Manual recordings target 5 seconds. Hidden tabs cancel captures; unsupported metrics show N/A and missing samples show —.
- Advanced: tasks / blocking / input queue
- Long tasks occupy the main thread for at least 50ms. Blocking sums only each task’s portion above 50ms, clipped to the recording. Timer delay is lateness of a 50ms timer, not frame latency. Input queue delay is event time to processing start for qualifying observed inputs; continuous pointermove/drag events are not included.
- Optional FPS details
- FPS counts actual animation callbacks per second over the sampler’s window, not displayed frames. Average interval is mean callback spacing; p95 and max expose slower callbacks. “Late” means a gap above 25ms, using a fixed 60Hz reference (1.5 × 16.7ms); it is not a count of GPU-dropped frames. This secondary meter warms up after changes and pauses while textures are being prepared.
- Advanced: long animation frames
- Where the browser supports it, we record complete frames lasting at least 50ms. Duration covers the long UI update; its render phase and input-blocking time are separate quantities. Neither includes every async GPU or compositor stall. N/A means unavailable, not zero cost.
Test: 1s settling + 3s sampling per pass, first with zero blobs, then your instances. Resize mode changes each surface’s width/height, even when paused. Live sampling continues while dragging. These are page-wide rendering estimates; GPU presentation can still stutter with healthy callbacks.
Page JavaScript cannot read compositor presentation for HTML/CSS/SVG. In Chrome, open DevTools → More tools → Rendering → Frame rendering stats to see dropped and partially presented frames while dragging. For an article, record Performance, run “Test resizing”, then inspect Frames, Main, Paint and GPU/raster tracks. Look for the named “Blob lab” intervals in Timings. A low timer or callback reading does not prove smooth presentation.
Chrome frame diagnostics ↗Why callback FPS can miss stutter ↗Long Tasks API unavailable
Page-wide tasks ≥50ms
Max — ms
Event Timing unavailable
Long Animation Frames unavailable
Scheduling delay · p95
Waiting for samplesWorst — ms / last 5sTimer delay · peaks / 250ms · updates twice a second
Record the zero-blob baseline, return to blobs, and record the same workload. Type or drag during recording to test interaction. Mixed settings are marked; use matching settings for a steady-scene comparison.
Long-task blocking is the portion beyond 50ms, measured within this window; it is not Lighthouse TBT or total CPU usage. LoAF duration includes the full long animation frame; its blockingDuration can be small even when a frame is slow. Render phase is frame end minus renderStart and excludes later GPU presentation. The rAF → following-task probe includes rendering opportunity and scheduling, not pure paint time. Timer lateness is a secondary responsiveness probe. Input samples include qualifying Event Timing entries (duration ≥16ms), not every keystroke or a full INP score. Continuous pointermove/drag events are not covered by Event Timing. Unsupported APIs show N/A.
These measurements include this page and its monitor. They cannot attribute a task to a React component or measure GPU raster cost. For attribution, record Chrome DevTools → Performance → Main, then inspect scripting, style/layout and paint. Each completed capture adds a named Blob lab interval in User Timings to find the matching period. Use a production build; keep the tab visible. Zero blocking time can still accompany expensive rendering.