WebGL- und 3D-Erlebnisse
Ergänzt interaktive Webgrafik innerhalb begründeter Lade- und Gerätebudgets mit nutzbaren Alternativen und vollständiger Ressourcenfreigabe.
webgl-3d-experiences
Entdecke, wie der Skill hilftWann ist der Skill hilfreich?
Nutze ihn für 3D-Ansichten auf schwachen Geräten oder Browsern ohne verlässliches WebGL.
Wobei hilft er dir?
- Begründet 3D anhand von Lade- und Gerätebudgets.
- Lädt verzögert und bietet statische oder bewegungsarme Alternativen.
- Rendert bei Bedarf und gibt GPU-Ressourcen nach Kontextverlust oder Abbau frei.
Das könntest du fragen
Baue einen Produktbetrachter mit WebGL-Fallback und Ressourcenfreigabe beim Seitenwechsel. Simuliere Kontextverlust und wiederholtes Wegnavigieren. Stelle Viewer oder statische Alternative wieder her, ohne alte Texturen, Geometrien oder Animationsschleifen weiterzuführen.
Ausführliche Dokumentation
Hier findest du die ursprüngliche Anleitung, Beispiele und Prüfschritte des Skills in ihrer Originalsprache.
Weniger anzeigen
WebGL & 3D Experiences
Use WebGL, custom shaders, or 3D scenes only when spatial depth, interactive 3D inspection, or shader-driven visual effects deliver clear product value that CSS, SVG, or 2D Canvas cannot achieve at a fraction of the bundle and GPU cost.
Justification & Progressive Enhancement Gate
Before introducing Three.js or a custom WebGL pipeline:
- Bundle & initialization budget: Lazy-load 3D libraries (
await import('three')) behind anIntersectionObserveror route split so initial page load (LCP / TTI) is never blocked by a 150KB+ 3D engine. - Capability & fallback check: Gracefully handle missing WebGL contexts, software renderers, low-power devices, and
prefers-reduced-motion: reduceby rendering a crisp static image, SVG, or CSS gradient fallback underneath the canvas. - On-demand rendering (
frameloop="demand"): If the 3D scene only changes when the user drags, hovers, or scrolls, render on demand rather than running a continuous 60fpsrequestAnimationFrameloop that drains laptop and mobile batteries.
Performance & Fill-Rate Guardrails
- Clamp pixel ratio (
Math.min(window.devicePixelRatio, 2)): Rendering a full-viewport fragment shader or 3D scene atdevicePixelRatio = 3or4multiplies pixel fill-rate cost by $9\times$–$16\times$ with negligible visual gain and severe thermal throttling. - Shader & draw-call discipline:
- Keep draw calls low by merging static geometries or using
InstancedMeshfor repeated elements. - Pre-compile materials and avoid dynamic shader recompilation during user interaction.
- Keep DOM overlays (text, buttons, tooltips) in standard HTML/CSS above the
<canvas>(pointer-events: noneon the canvas unless dragging) rather than rendering UI text as 3D textures.
- Keep draw calls low by merging static geometries or using
Context Loss & Complete GPU Memory Disposal
Browsers evict WebGL contexts when background tabs accumulate or GPU memory is pressured, and SPA navigation leaks GPU VRAM if resources are not explicitly freed:
// 1. Handle WebGL context loss & restoration without crashing the page
canvas.addEventListener('webglcontextlost', (e) => {
e.preventDefault(); // Allows context to be restored later
renderer.setAnimationLoop(null);
});
canvas.addEventListener('webglcontextrestored', () => {
initSceneResources();
renderer.setAnimationLoop(animate);
});
// 2. Complete GPU resource disposal on component unmount
function disposeThreeScene(scene: THREE.Scene, renderer: THREE.WebGLRenderer) {
renderer.setAnimationLoop(null);
scene.traverse((obj) => {
if ((obj as THREE.Mesh).isMesh || (obj as THREE.Line).isLine) {
const mesh = obj as THREE.Mesh;
mesh.geometry?.dispose();
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
for (const mat of materials) {
if (!mat) continue;
for (const value of Object.values(mat)) {
if (value && typeof (value as THREE.Texture).dispose === 'function') {
(value as THREE.Texture).dispose();
}
}
mat.dispose();
}
}
});
renderer.dispose();
}
Enthaltene Dateien 1
SKILL.md
