Move your pointer across the water. Then stop, and watch the meter fall to zero. The loop is not throttled and it is not running a cheaper shader. It is cancelled, and it restarts on the next thing you do. The frames-never-drawn count is the part your battery notices.
Measured over the last second of wall time. Zero when idle, because nothing is running.
Total since the page loaded.
What an always-on loop would have drawn in the same wall time, at this display's measured refresh.
Three floats each: x, y, and the moment it was struck. No other per-ripple state exists.
The usual way to animate a struck object is a tween per object, ticked on the CPU every frame. Store the strike time instead and the whole envelope becomes a function of now - struck, evaluated in the fragment shader. The CPU keeps an array of twelve vec3s and touches it only when you move.
That is what makes stopping cheap. There is no tween mid-flight to unwind and no per-object state to keep coherent. When the last ripple's amplitude falls under the visible threshold, the loop has nothing left to say and exits.
// CPU: this is the entire per-ripple state ripples[i] = [x, y, nowSeconds]; // GPU: damped oscillator, evaluated fresh every frame from the timestamp float age = u_time - r.z; float env = exp(-age * 2.4); // dies out in about a second float wave = sin(dist * 46.0 - age * 9.0) * env; height += wave * smoothstep(0.55, 0.0, dist); // the loop is cancelled, not slowed, when nothing is left to draw if (idleFor > 2000 && peakAmplitude < 0.004) { cancelAnimationFrame(raf); raf = 0; // zero work until the next pointer event }
Chrome 152 ships navigator.cpuPerformance, a read-only integer from 1 to 4. Drop 041 uses it to seed an adaptive quality manager. Here it does one smaller job: it picks the starting resolution scale so a weak device never has to render one expensive frame before the measurement catches up.
It returns 0 when the browser cannot classify the device, and that case is handled on its own line. Reading 0 as a tier would quietly seed every unclassified visitor to the worst path, which is the opposite of the point. On anything without the API at all, the scale starts at a safe middle and the frame timer takes over from there.
The tier picks where quality starts. It never sets a ceiling. A fast machine misread as slow still climbs on measured frame time.
Unclassified means unknown, so it falls to the same middle default as a browser with no API at all.
Users can override it in Chrome settings and enterprise policy can set it. Anything that treats it as a gate is broken by design.