Stock hero images are dead. Every designer-led site now ships a 3D scene or shader, which means generative art is table stakes for premium portfolios. The problem: p5.js out-of-the-box is slow. A naive particle system with 10k points will crater mobile to 15fps, drain battery in 8 minutes, and tank your SEO. Here's how we ship generative heroes that actually convert — and your users don't curse your browser tab.
Why p5.js Over Raw Canvas
p5.js is Processing for the web. You write `function draw()`, call `rect()` and `circle()`, and it handles the render loop. Zero WebGL boilerplate. That simplicity is poison on production sites — until you switch to WebGL2 mode.
{`function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
// WEBGL mode: 100× faster particle math than default 2D
}`}
WebGL mode is the move. Your draw code stays the same — you still call `push()`, `translate()`, `sphere()` — but it's now hitting the GPU. A particle system that crawls at 60k points in 2D mode runs 500k points at 45fps in WebGL.
Production Architecture
Skip individual point updates. Use instanced rendering: one geometry, thousands of positions. Pre-allocate a `Float32Array` for particle positions, update it in a typed loop, bind it once:
{`const positions = new Float32Array(particleCount * 3);
let idx = 0;
for (let i = 0; i < particleCount; i++) {
positions[idx++] = random(-w, w); // x
positions[idx++] = random(-h, h); // y
positions[idx++] = random(-200, 200); // z
}
// Bind positions to vertex buffer, update once per frame`}
Mobile throttle: halve the point count on phones, skip post-processing, lock canvas to 30fps via RAF throttle. Test on actual iPhone hardware — simulator FPS is fiction.
Accessibility & Battery
Check `prefers-reduced-motion` at startup. If set, render a static single frame and kill the animation loop. No performance penalty, users still see the art.
{`const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (prefersReduced) {
draw(); // render once
noLoop(); // kill animation
}`}
Pause on blur too — when the tab loses focus, stop the RAF call. Resume on focus. Saves ~70% battery on background tabs.
The Catch
Generative art is a hero feature, not a content container. Don't dump text onto it — lay text below, side-by-side, or in a masked region. And beware: p5.js + Webpack dev builds are slow to load. Tree-shake aggressively or use a CDN build.
The Verdict
Generative art used to require Three.js or raw WebGL expertise. p5.js + WebGL mode flattens the curve — you can ship a studio-quality particle hero in a weekend. Switch to WebGL, instance your geometry, throttle on mobile, respect prefers-reduced-motion, and test on hardware. See a live example at /pricing, or read shader foundations at /blog/glsl-shader-backgrounds-marketing-sites.