Signatur
Beschreibung
Mit decode() forderst du den Browser auf, das über href referenzierte Bild eines SVG-<image>-Elements zu laden und vollständig zu dekodieren, bevor du es in das sichtbare SVG bzw. DOM einfügst. Das zurückgegebene Promise wird erfüllt, sobald die Bilddaten dekodiert sind. Das Bild lässt sich dann ohne Flackern und ohne Blockieren des Haupt-Threads beim nächsten Rendern darstellen.
Das ist vor allem sinnvoll bei großen Rastergrafiken in SVG-Diagrammen, Karten, Galerien oder Animationen: Ohne decode() kann das Einfügen eines frisch geladenen Bildes zu einem sichtbaren Ruckler führen, weil die Dekodierung erst beim ersten Zeichnen passiert. Mit decode() dekodiert der Browser das Bild im Hintergrund, du tauschst es erst danach aus.
Schlägt das Laden oder Dekodieren fehl (ungültige URL, beschädigte Datei, nicht unterstütztes Format), wird das Promise mit einer DOMException vom Typ EncodingError abgelehnt. Die Methode funktioniert genauso wie HTMLImageElement.decode(), nur für SVG-Bildelemente.
Rückgabewert
Promise, das mit undefined erfüllt wird, sobald das Bild dekodiert ist. Es wird mit einer DOMException (EncodingError) abgelehnt, wenn das Bild nicht geladen oder dekodiert werden kann.Beispiele
Bild erst nach dem Dekodieren ins SVG einfügen
const SVG_NS = 'http://www.w3.org/2000/svg';
const svg = document.querySelector('svg#karte');
const img = document.createElementNS(SVG_NS, 'image');
img.setAttribute('href', '/tiles/zoom-12.png');
img.setAttribute('width', '512');
img.setAttribute('height', '512');
try {
await img.decode();
svg.appendChild(img); // erscheint ohne Flackern
console.log('Kachel eingefügt');
} catch (err) {
console.error('Dekodieren fehlgeschlagen:', err.name);
}
Flackerfreier Bildwechsel mit Fallback
const SVG_NS = 'http://www.w3.org/2000/svg';
const swapImage = async (oldImg, url) => {
const next = document.createElementNS(SVG_NS, 'image');
for (const attr of ['x', 'y', 'width', 'height']) {
if (oldImg.hasAttribute(attr)) next.setAttribute(attr, oldImg.getAttribute(attr));
}
next.setAttribute('href', url);
try {
await next.decode();
oldImg.replaceWith(next);
return true;
} catch {
// Altes Bild bleibt stehen, wenn das neue kaputt ist
return false;
}
};
const ok = await swapImage(document.querySelector('#avatar'), '/img/avatar-neu.webp');
console.log(ok ? 'Bild gewechselt' : 'Wechsel abgebrochen');
Mehrere Bilder parallel dekodieren
const SVG_NS = 'http://www.w3.org/2000/svg';
const urls = ['/sprites/a.png', '/sprites/b.png', '/sprites/c.png'];
const images = urls.map((url, i) => {
const img = document.createElementNS(SVG_NS, 'image');
img.setAttribute('href', url);
img.setAttribute('x', String(i * 64));
img.setAttribute('width', '64');
img.setAttribute('height', '64');
return img;
});
const results = await Promise.allSettled(images.map((img) => img.decode()));
const group = document.querySelector('svg g#sprites');
results.forEach((r, i) => {
if (r.status === 'fulfilled') group.appendChild(images[i]);
else console.warn(`Übersprungen: ${urls[i]}`);
});
console.log(`${group.childElementCount} Sprites bereit`);
Funktionsprüfung mit Fallback auf das load-Event
const decodeSvgImage = (img) =>
typeof img.decode === 'function'
? img.decode()
: new Promise((resolve, reject) => {
img.addEventListener('load', () => resolve(), { once: true });
img.addEventListener('error', () => reject(new Error('Ladefehler')), { once: true });
});
const img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
img.setAttribute('href', '/img/logo.png');
await decodeSvgImage(img);
console.log('Bereit zum Einfügen');
// Wichtig · Fallstricke
- Zuerst
hrefsetzen, danndecode()aufrufen: Ohne Bildquelle lehnt der Browser das Promise mitEncodingErrorab. Nimm das Attributhref; das veraltetexlink:hrefgeht zwar noch, sollte aber nur für sehr alte Umgebungen verwendet werden. - Element immer mit
createElementNSerzeugen:document.createElement('image')erzeugt keinSVGImageElement, und die Methode fehlt dann. - Immer mit
try/catchoder.catch()absichern: Kaputte Dateien, falsche MIME-Typen oder Netzwerkfehler führen zu einer Ablehnung. Unbehandelt erscheint dann eineunhandledrejection-Warnung. - Kein Ersatz für Caching: Der Browser kann die dekodierten Daten später wieder verwerfen, etwa bei Speicherdruck oder wenn das Element lange nicht im DOM hängt. Füge das Bild deshalb möglichst direkt nach dem Erfüllen des Promise ein.
- Cross-Origin: Für Bilder von fremden Domains gelten die normalen CORS- und CSP-Regeln (
img-src). Blockiert eine Content-Security-Policy die Quelle, wird das Promise abgelehnt. - Browser-Unterstützung: Aktuelle Chromium-Browser, Firefox und Safari unterstützen die Methode. Ältere Browser kennen sie teilweise nicht. Prüfe dort mit
typeof img.decode === 'function'und greife auf die Eventsloadunderrorzurück.