Was ist ein Shader?
Ein Shader ist ein kurzes Programm, das nicht auf dem Prozessor, sondern auf der Grafikkarte ausgeführt wird. Die Grafikkarte ist darauf gebaut, sehr viele einfache Rechnungen gleichzeitig zu erledigen. Genau das nutzt ein Shader aus. Er beschreibt eine Regel, und die Grafikkarte wendet diese Regel parallel auf jeden einzelnen Bildpunkt an, viele Male pro Sekunde.
Im Webdesign begegnen dir vor allem zwei Arten. Der Vertex-Shader legt fest, wo die Eckpunkte einer Form liegen. Der Fragment-Shader, auch Pixel-Shader genannt, bestimmt die Farbe jedes Bildpunkts innerhalb dieser Form. Für flächige Effekte wie bewegte Verläufe reicht oft ein einziges Rechteck über die ganze Fläche, und die ganze Gestaltung passiert im Fragment-Shader.
WebGL, WebGPU und die Sprache dahinter
Im Browser laufen Shader über WebGL. Geschrieben werden sie in GLSL, einer Sprache, die an C erinnert. Mit WebGPU gibt es eine neuere Schnittstelle, die mehr Leistung bietet und eine eigene Sprache namens WGSL nutzt. Für die meisten Effekte auf Websites reicht WebGL, weil es in praktisch allen aktuellen Browsern läuft.
Wofür Shader im Webdesign taugen
Shader lohnen sich dort, wo ein Effekt lebendig wirken soll, ohne ein schweres Video zu laden. Typische Einsätze sehen so aus.
- Bewegte Farbverläufe und Mesh-Gradients als Hintergrund für Hero oder Call-to-Action
- Körnung und Rauschen, die einer Fläche Tiefe geben
- Verzerrungen wie Glas, Wasser oder Wellen, etwa auf einem Logo oder Bild
- Partikel, die auf die Maus reagieren
- Dreidimensionale Objekte und Szenen
Ein Shader ersetzt dabei oft mehrere Megabyte Video durch wenige Kilobyte Code. Das ist der eigentliche Vorteil, solange die Rechenlast auf dem Gerät im Rahmen bleibt.
Drei Wege, Shader in WordPress einzubauen
Eigener Code im HTML-Widget
Der direkteste Weg ist ein Canvas-Element mit etwas JavaScript, in Elementor über das HTML-Widget, im Block-Editor über den HTML-Block. Du brauchst dafür kein Plugin und hast die volle Kontrolle über Farben, Tempo und Verhalten. Der Nachteil ist, dass du WebGL-Grundlagen verstehen musst.
Das folgende Beispiel zeigt einen animierten Verlauf ohne Bibliothek. Es pausiert, sobald die Fläche aus dem Sichtbereich scrollt, begrenzt die Pixeldichte und bleibt stehen, wenn im Betriebssystem „Bewegung reduzieren“ aktiv ist.
<!-- Animierter Verlauf als Fragment-Shader, ohne Bibliothek.
Fuer ein Elementor HTML-Widget. Die Leinwand ist rein dekorativ (aria-hidden),
pausiert ausserhalb des Sichtbereichs und respektiert "Bewegung reduzieren". -->
<canvas class="sp-shader" aria-hidden="true"></canvas>
<style>
.sp-shader{display:block;width:100%;height:420px;border-radius:24px;background:#141418}
</style>
<script>
(function(){
var c = document.querySelector('.sp-shader');
var gl = c && c.getContext('webgl');
if(!gl) return; // ohne WebGL bleibt die Hintergrundfarbe stehen
var vs = 'attribute vec2 p;void main(){gl_Position=vec4(p,0.,1.);}';
var fs = 'precision mediump float;uniform vec2 r;uniform float t;' +
'void main(){vec2 uv=gl_FragCoord.xy/r;' +
'float w=sin(uv.x*3.+t*.6)*.5+sin(uv.y*4.-t*.4)*.5;' +
'vec3 a=vec3(.71,.70,1.);vec3 b=vec3(.62,.85,1.);' +
'vec3 col=mix(vec3(.08),mix(a,b,uv.x),smoothstep(-.6,1.,w)*.55);' +
'gl_FragColor=vec4(col,1.);}';
function sh(type, src){var s=gl.createShader(type);gl.shaderSource(s,src);gl.compileShader(s);return s;}
var pr = gl.createProgram();
gl.attachShader(pr, sh(gl.VERTEX_SHADER, vs));
gl.attachShader(pr, sh(gl.FRAGMENT_SHADER, fs));
gl.linkProgram(pr); gl.useProgram(pr);
var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,-1,1,-1,-1,1,1,1]), gl.STATIC_DRAW);
var loc = gl.getAttribLocation(pr, 'p');
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
var uR = gl.getUniformLocation(pr, 'r'), uT = gl.getUniformLocation(pr, 't');
var still = matchMedia('(prefers-reduced-motion: reduce)').matches;
var run = false, raf = 0;
function size(){
var d = Math.min(window.devicePixelRatio || 1, 1.5); // Pixeldichte begrenzen spart GPU-Last
c.width = c.clientWidth * d; c.height = c.clientHeight * d;
gl.viewport(0, 0, c.width, c.height);
}
function draw(ms){
gl.uniform2f(uR, c.width, c.height);
gl.uniform1f(uT, still ? 0 : ms / 1000);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
if(run && !still) raf = requestAnimationFrame(draw);
}
new IntersectionObserver(function(e){
run = e[0].isIntersecting;
if(run){ raf = requestAnimationFrame(draw); } else { cancelAnimationFrame(raf); }
}).observe(c);
addEventListener('resize', size); size();
})();
</script>
Eine Bibliothek wie Three.js
Für komplexere Effekte und 3D lohnt eine Bibliothek. Three.js ist die bekannteste, sie nimmt dir den Aufbau von Szene, Kamera und Materialien ab, und du schreibst nur noch den eigentlichen Shader. Schlankere Alternativen wie OGL eignen sich, wenn du vor allem flächige Effekte brauchst und jedes Kilobyte zählt. Die Bibliothek lädst du in WordPress am besten über die functions.php oder ein Snippet-Plugin, und zwar nur auf den Seiten, die den Effekt wirklich zeigen.
No-Code-Tools mit Embed
Es gibt Werkzeuge, in denen du Shader-Effekte visuell zusammenstellst und am Ende einen Embed-Code bekommst, zum Beispiel Unicorn Studio oder Spline für 3D. Das ist der schnellste Weg zu einem Ergebnis. Achte dabei darauf, welche Skripte von fremden Servern nachgeladen werden. Das betrifft die Ladezeit und, je nach Anbieter, auch den Datenschutz.
Performance, damit der Effekt die Seite nicht ausbremst
Ein Shader rechnet, solange er läuft. Auf einem Laptop merkt man das kaum, auf einem älteren Smartphone im Akku. Bei jedem Shader halte ich mich an diese Punkte.
- Der Shader ist nie das größte Element im ersten Bildschirm. Text oder ein Bild übernehmen den LCP, der Effekt kommt dazu
- Außerhalb des Sichtbereichs pausiert die Animation, gesteuert über den IntersectionObserver
- Die Pixeldichte wird begrenzt, weil ein Retina-Display sonst die vierfache Fläche berechnet
- Das Skript startet erst, wenn der restliche Seiteninhalt steht. In WP Rocket gehören solche Skripte deshalb bewusst in die verzögerte Ausführung oder bewusst ausgenommen, je nachdem, ob der Effekt sofort sichtbar sein muss
- Ohne WebGL bleibt eine passende Hintergrundfarbe oder ein statisches Bild stehen
Wie du die Ladezeit deiner Seite danach misst und wo die üblichen Bremsen in Elementor liegen, steht im Artikel zu den Core Web Vitals in Elementor.
Barrierefreiheit nicht vergessen
Bewegte Flächen können Menschen mit Gleichgewichtsstörungen oder Migräne Probleme bereiten. Wer im Betriebssystem „Bewegung reduzieren“ eingestellt hat, sollte deshalb einen ruhigen Zustand sehen. Die Abfrage dafür ist eine Zeile, prefers-reduced-motion. Ist der Shader rein dekorativ, bekommt das Canvas-Element außerdem aria-hidden, damit Screenreader es überspringen. Mehr zu den Grundlagen steht im Ratgeber zum barrierefreien Webdesign.