Signatur
Beschreibung
Das Ereignis webglcontextlost wird an einem HTMLCanvasElement ausgelöst, sobald der Browser feststellt, dass der zugehörige WebGLRenderingContext bzw. WebGL2RenderingContext verloren gegangen ist. Typische Ursachen sind ein Absturz oder Reset des Grafiktreibers, zu viele gleichzeitig aktive WebGL-Kontexte, ein Wechsel der GPU (z. B. bei Laptops mit zwei Grafikkarten), Energiesparmaßnahmen auf Mobilgeräten oder ein bewusster Aufruf von WEBGL_lose_context.loseContext().
Nach dem Verlust sind alle GPU-Ressourcen ungültig: Texturen, Puffer, Shader, Programme und Framebuffer müssen später neu angelegt werden. WebGL-Aufrufe schlagen stillschweigend fehl, gl.isContextLost() liefert true, und gl.getError() gibt gl.CONTEXT_LOST_WEBGL zurück.
Ganz wichtig: Standardmäßig versucht der Browser nicht, den Kontext wiederherzustellen. Nur wenn der Handler event.preventDefault() aufruft, signalisiert die Anwendung, dass sie die Wiederherstellung selbst übernimmt. Dann kann später das Ereignis webglcontextrestored folgen, in dem man alle Ressourcen neu erzeugt und die Render-Schleife wieder startet.
Registriert wird das Ereignis per addEventListener("webglcontextlost", handler) oder über die Eigenschaft canvas.onwebglcontextlost. Das übergebene Ereignisobjekt ist ein WebGLContextEvent mit der Eigenschaft statusMessage, die optional weitere Informationen des Browsers enthält.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "webglcontextlost". |
|
| $handler Pflicht | (event: WebGLContextEvent) => void | Callback, der ein WebGLContextEvent erhält. Rufen Sie darin event.preventDefault() auf, um die Wiederherstellung zu ermöglichen. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once, passive oder signal. Achtung: Mit passive: true wird preventDefault() ignoriert. |
Rückgabewert
addEventListener gibt nichts zurück. Das Ereignisobjekt ist ein WebGLContextEvent (erbt von Event) mit der Eigenschaft statusMessage (string).Beispiele
Kontextverlust abfangen und Wiederherstellung ermöglichen
const canvas = document.querySelector('#scene');
const gl = canvas.getContext('webgl2');
let frameId = null;
const render = () => {
gl.clearColor(0.1, 0.2, 0.3, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
frameId = requestAnimationFrame(render);
};
canvas.addEventListener('webglcontextlost', (event) => {
event.preventDefault(); // ohne diesen Aufruf keine Wiederherstellung!
cancelAnimationFrame(frameId);
console.warn('WebGL-Kontext verloren:', event.statusMessage || '(keine Details)');
});
canvas.addEventListener('webglcontextrestored', () => {
console.info('WebGL-Kontext wiederhergestellt');
// hier Shader, Puffer und Texturen neu anlegen
render();
});
render();
Kontextverlust gezielt simulieren (Tests)
const canvas = document.createElement('canvas');
document.body.append(canvas);
const gl = canvas.getContext('webgl');
const ext = gl.getExtension('WEBGL_lose_context');
canvas.onwebglcontextlost = (event) => {
event.preventDefault();
console.log('verloren, isContextLost():', gl.isContextLost());
// nach 1 Sekunde Wiederherstellung anstoßen
setTimeout(() => ext.restoreContext(), 1000);
};
canvas.onwebglcontextrestored = () => {
console.log('wieder da, isContextLost():', gl.isContextLost());
};
ext?.loseContext();
Ressourcen-Verwaltung mit zentraler Init-Funktion
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2');
let resources = null;
const initResources = () => {
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 1, -1, -1, 1, -1]), gl.STATIC_DRAW);
return { buffer };
};
const controller = new AbortController();
canvas.addEventListener('webglcontextlost', (e) => {
e.preventDefault();
resources = null; // alte Handles sind ungültig
document.body.classList.add('gpu-lost');
}, { signal: controller.signal });
canvas.addEventListener('webglcontextrestored', () => {
resources = initResources();
document.body.classList.remove('gpu-lost');
}, { signal: controller.signal });
resources = initResources();
// Beim Abbau der Komponente alle Listener entfernen:
// controller.abort();
// Wichtig · Fallstricke
- Ohne
preventDefault()keine Wiederherstellung: Rufen Sie den Handler ohne diesen Aufruf auf, bleibt der Kontext dauerhaft verloren, undwebglcontextrestoredwird nie ausgelöst. Registrieren Sie den Listener daher nicht mitpassive: true. - Nach dem Verlust sind alle WebGL-Objekte (
WebGLTexture,WebGLBuffer,WebGLProgram…) ungültig. Verwenden Sie sie nach der Wiederherstellung nicht weiter, sondern legen Sie sie neu an. Das Kontextobjektglselbst bleibt aber dasselbe. - Stoppen Sie die Render-Schleife (
cancelAnimationFrame), damit keine sinnlosen Aufrufe laufen. WebGL-Aufrufe werfen im verlorenen Zustand keine Fehler, sondern bewirken einfach nichts. - Browser begrenzen die Zahl gleichzeitig aktiver WebGL-Kontexte (oft etwa 16). Wird ein neuer angelegt, verliert der älteste seinen Kontext. Geben Sie nicht mehr benötigte Kontexte deshalb mit
WEBGL_lose_context.loseContext()frei. statusMessageist in den meisten Browsern leer, eignet sich also nicht für eine verlässliche Fehlerauswertung.- Das Ereignis wird auch an
OffscreenCanvasausgelöst. Es ist in allen modernen Browsern verfügbar. Zum Testen eignet sich die ErweiterungWEBGL_lose_context.