Start · Sprachen · JavaScript · Referenz · SVGImageElement.decode()

SVGImageElement.decode()

Methode

Startet das asynchrone Dekodieren des Bildes eines SVG-<code>&lt;image&gt;</code>-Elements und gibt ein <code>Promise</code> zurück, das sich erfüllt, sobald das Bild ohne Verzögerung dargestellt werden kann.

seit JavaScript Moderne Browser (Chromium, Firefox, Safari); in äl Kategorie: webapi

Signatur

SVGImageElement.prototype.decode()

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

Typ
Promise<undefined>
Beschreibung
Ein 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);
}
Kachel eingefügt

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');
Bild gewechselt

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`);
3 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');
Bereit zum Einfügen

// Wichtig · Fallstricke

  • Zuerst href setzen, dann decode() aufrufen: Ohne Bildquelle lehnt der Browser das Promise mit EncodingError ab. Nimm das Attribut href; das veraltete xlink:href geht zwar noch, sollte aber nur für sehr alte Umgebungen verwendet werden.
  • Element immer mit createElementNS erzeugen: document.createElement('image') erzeugt kein SVGImageElement, und die Methode fehlt dann.
  • Immer mit try/catch oder .catch() absichern: Kaputte Dateien, falsche MIME-Typen oder Netzwerkfehler führen zu einer Ablehnung. Unbehandelt erscheint dann eine unhandledrejection-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 Events load und error zurück.