How to add a WebGL background in Framer without slowing your site down
Animated backgrounds get blamed for slow Framer sites, but the shader is rarely the problem. Here is what actually costs you, and how to pick the right background for each section.
A WebGL background is the fastest way to make a Framer site feel alive, and the fastest way to make it feel broken. When people blame the shader, they are usually blaming the wrong thing. The maths running on the GPU is rarely the problem. What costs you is everything around it: how often it runs, at what resolution, and whether it ever stops.
This is a practical guide to shipping one without regret.
What a full-screen shader actually costs
A shader background redraws every frame. At 60fps that is sixty full-screen repaints a second, and each repaint runs your fragment program once per pixel. On a 1440-wide laptop at a device pixel ratio of 2, a full-screen background is roughly four million pixels per frame — a quarter of a billion fragment operations per second.
Modern GPUs handle that comfortably. That is exactly why the problem sneaks up on you: one shader on one screen looks fine on your machine, so you add another.
The compounding problem
The moment a page has two or three animated sections, the cost stops being about any single one. The browser has a frame budget of about sixteen milliseconds. Scrolling, layout, image decoding and your animations all share it. Miss the budget and the visitor does not see a slow shader — they see janky scrolling, which they attribute to your whole site.
The failure mode is not a frame rate counter. It is someone flicking down the page, feeling it stutter, and leaving.
Phones are a different machine
A mid-range Android phone has a fraction of the GPU headroom and no active cooling. Sustained full-screen shader work makes it warm, and once it is warm the system throttles — so the site that was smooth for the first ten seconds degrades exactly when someone has decided to read. Battery drain compounds it. Test on a real mid-range device, not a simulator on a desktop GPU.
Fix one: stop drawing when nobody is looking
This is the single highest-value change, and most animated backgrounds on the web do not do it.
An animated background should observe its own visibility and stop rendering when it leaves the viewport. Attach an IntersectionObserver to the component's own element; when it leaves, cancel the animation frame loop; when it returns, start it again.
What pausing has to actually mean
Cancel the loop. Do not merely hide the element or drop its opacity to zero — a hidden element with a running requestAnimationFrame loop costs precisely as much as a visible one. The browser has no idea you consider it invisible.
This matters because the intuitive fixes are the ineffective ones. Setting opacity: 0, moving the element off screen, or covering it with another section all leave the loop running. Only cancelling the frame callback stops the work.
Why this changes the maths
With this in place, a full-screen shader costs about as much as a static image once it has scrolled past. That is the difference between a page that can carry three animated sections and a page that struggles with one. Every background in the Depth library ships with this built in, because it is not optional at any realistic page length.
Fix two: render without a browser
Framer draws your component on the canvas while you design, and again when it generates thumbnails and exports. Those environments have no live animation loop. A component that assumes a browser will either throw or render an empty rectangle.
Gate the animation behind a static-renderer check and return a still frame instead. Two things depend on that fallback being good: what a designer sees on the canvas while deciding whether to use the component at all, and what appears in previews and social cards.
A frozen frame beats an approximation
The tempting shortcut is to fake the static state with a CSS gradient. It rarely holds up — the fallback and the live effect look like two different products, and the canvas stops being a reliable preview of the page. Capturing a real frame of the shader and using that as the still image is more work once and correct forever.
Fix three: stop rendering more pixels than you need
Device pixel ratio is the quiet multiplier. Rendering at DPR 3 on a modern phone means nine times the fragment work of DPR 1 for a background that is, by definition, out of focus behind your content.
Cap the render resolution. For a soft gradient, noise field or blurred shape, rendering at DPR 1.5 — or even 1 — is visually indistinguishable from full resolution, because there are no hard edges for anyone to notice. Sharp geometric patterns need more; organic ones need remarkably little.
This one change often halves the cost of a background with no visible difference at all.
Choosing the right background for the position
Performance work only matters if the background deserved to be there. Different positions on a page want different things.
Heroes want motion
This is where movement earns its keep, because the visitor is still deciding whether to keep scrolling. Shaders and noise fields read as atmosphere rather than as an effect. Give a hero background room, and make it the only animated thing on that screen — two competing animations in one viewport read as chaos rather than craft.
Interior sections want to lose
Below the fold, the text has to win. Gradients, glass and progressive blur sit behind copy without competing with it. A reliable test: if you find yourself adding a dark scrim to make the text legible, the background is too busy for that position. Change the background rather than patching it with an overlay.
Editorial pages want texture, not motion
Dithered and halftone treatments hold their character at large sizes without banding, which is why they suit long-form and brand-led pages where a smooth gradient reads as generic. They are also often cheaper, because texture does not require animation to work.
Respect the visitor who asked you to stop
Some people have reduced motion enabled at the system level, for reasons ranging from preference to vestibular disorders. Honour it. A reduced-motion visitor should get the still frame — a coherent, designed background, not an empty box where the effect used to be.
Treat that path as a real design state rather than an accessibility checkbox, and it doubles as your static fallback.
A pre-launch checklist
Before you ship a page with an animated background, run these five checks.
Scroll the entire page on a mid-range phone and watch for stutter, not just frame rate. Load it on a throttled connection — a background that pops in late is worse than one that was never there. Turn on reduced motion and confirm the page still looks finished. Put two instances on one page deliberately and confirm the off-screen one is genuinely idle. Finally, look at the canvas and the exported thumbnail, because that is what everyone sees before they see the real thing.
When not to use one at all
An animated background is a poor fit on pages where the visitor has a task: checkout, forms, documentation, pricing comparisons. Motion behind a form competes with the thing you want completed. The most disciplined use is one hero, everything else static — and that restraint tends to read as more premium, not less.
Get all of this right and an animated background stops being a performance liability and goes back to being what it should be: the first thing someone notices, for the right reason.