Skip to content
Free audit Get a quote
PerformanceCSSFrontendGuide

60 fps or nothing: what we learned polishing the performance of our own site

Pablo Huget · · 2 min read
60 fps or nothing: what we learned polishing the performance of our own site

Our site has WebGL smoke, a canvas full of orbits, infinite marquees, twinkling stars and a grainy background. And it runs smooth at 60 fps. Getting there was a matter of measuring layer by layer instead of guessing. Here's what we learned, chapter and verse, to save you the trip.

The golden rule: transform and opacity, nothing else

The browser paints in layers. Animating transform or opacity only moves layers that are already painted (the GPU handles it, for free). Animating almost anything else (filter, box-shadow, width, background-position over large areas) forces a repaint on every frame. One small element gets a pass; twenty elements don't.

Trap #1

Stars that "breathe" by animating filter: drop-shadow get re-rasterized 60 times per second; with ~25 on screen, noticeable stuttering. Ours breathe with transform: scale() and the glow is static. Identical look, zero cost.

mix-blend-mode and filter: the silent killers

A hero with mix-blend-mode for the noise and filter: blur(90px) for the glows, on top of a canvas that repaints every frame, sinks to 5 fps: the blend forces the whole screen to recompose and the blur re-blurs on every repaint. The recipe: glows with pre-blurred radial-gradient (no filter) and zero blend modes over anything animated. Same look, 60 fps.

The rAF loops nobody sees

A ball of light that follows the cursor with smooth interpolation is pretty, and also a requestAnimationFrame loop running always if nobody stops it, even when the mouse has been still for a minute. Every continuous effect has to answer three questions: does it pause off screen? (IntersectionObserver), does it pause when the tab is hidden? (visibilitychange), does it stop when idle? If any answer is no, it's stealing battery.

backdrop-filter: you pay on every scroll

A header with backdrop-filter: blur(16px) re-blurs whatever's behind it on every scroll frame. We dropped to 12px and lightened the background: same glass, smaller bill. If your site "stutters when you scroll", start here.

/* BAD: repaints every frame */
.star { animation: glow 2s infinite; }
@keyframes glow { 50% { filter: drop-shadow(0 0 9px gold); } }

/* GOOD: pure compositor, same effect */
.star { filter: drop-shadow(0 0 5px gold); /* static */ }
@keyframes glow { 50% { transform: scale(1.1); } }

How we measured it

No intuition: DevTools → Performance with CPU x4, the Paint flashing layer turned on (if something flashes green during an animation, you're repainting), and real recordings on a modest laptop. The site has to run smooth on your client's computer, not yours.

60
hero fps with every layer on
0
filter/shadow animations when idle
x4
CPU throttling on every test

An animation that drops below 60 fps isn't an effect: it's a bug with glitter on it.

Pablo Huget, Web Developer at Intervolutions
Pablo Huget
Web Developer · Pixel artist
Web developer at Intervolutions. Interface, performance and detail: he reads a screen down to the 16×16 grid.
What we do about this when the project is yours

Share this

Link to this page: https://intervolutions.com/devlog/60fps-o-nada-rendimiento-web/

What will your website cost?

Pick what you need, add extras if you want, and watch the price range and timeline update as you go. When it looks right, send it and we reply with a fixed price within one business day.