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

HTMLImageElement.decode()

Methode

Gibt ein Promise zurück, das erfüllt wird, sobald das Bild geladen und decodiert ist und ohne Ruckeln ins DOM eingefügt werden kann.

seit JavaScript Baseline: alle modernen Browser (Chrome 64+, Firef Kategorie: webapi

Signatur

HTMLImageElement.prototype.decode()

Beschreibung

Mit decode() wird der Browser angewiesen, ein Bild vorab zu laden und zu decodieren, also in Pixeldaten umzuwandeln. Das zurückgegebene Promise wird erfüllt, wenn das Bild fertig decodiert ist. Wird es erst dann ins DOM eingefügt oder ausgetauscht, erscheint es ohne sichtbaren Aufbau, ohne Flackern und ohne dass der Haupt-Thread beim ersten Zeichnen wegen der Decodierung hängt.

Im Vergleich zum load-Event hat das zwei Vorteile: Erstens garantiert load nur, dass die Daten geladen sind, nicht dass sie auch decodiert wurden. Zweitens lässt sich decode() mit async/await verwenden und kommt ohne Callback-Verschachtelung aus.

Typische Einsatzfälle sind Bildergalerien und Karussells, das Austauschen von Platzhaltern gegen hochauflösende Bilder (LQIP), Bilder vorab laden, bevor eine Animation startet, und das Zeichnen auf ein <canvas>, sobald das Bild bereit ist.

Wenn das Bild nicht geladen oder nicht decodiert werden kann, etwa bei einer ungültigen URL, einem beschädigten Format oder einem leeren src, wird das Promise mit einer DOMException vom Typ EncodingError abgelehnt.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das mit undefined erfüllt wird, sobald das Bild decodiert ist. Kann das Bild nicht geladen oder decodiert werden, wird es mit einer DOMException (EncodingError) abgelehnt.

Beispiele

Bild ohne Flackern einfügen

const img = new Image();
img.src = '/bilder/hero.jpg';
img.alt = 'Titelbild';

try {
  await img.decode();
  document.querySelector('#hero').append(img);
  console.log('Bild eingefügt:', img.naturalWidth, 'x', img.naturalHeight);
} catch (err) {
  console.error('Bild konnte nicht decodiert werden:', err.name);
}
Bild eingefügt: 1920 x 1080

Platzhalter gegen hochauflösendes Bild tauschen

const swapToHighRes = async (placeholder) => {
  const hiRes = new Image();
  hiRes.src = placeholder.dataset.fullSrc;
  hiRes.alt = placeholder.alt;
  try {
    await hiRes.decode();
    placeholder.replaceWith(hiRes); // Austausch erst, wenn Pixel bereit sind
  } catch {
    console.warn('Hochauflösende Version nicht verfügbar:', hiRes.src);
  }
};

document.querySelectorAll('img[data-full-src]').forEach(swapToHighRes);

Mehrere Bilder vorladen, dann Galerie starten

const urls = ['/g/1.webp', '/g/2.webp', '/g/3.webp'];

const preload = (url) => {
  const img = new Image();
  img.src = url;
  return img.decode().then(() => img);
};

const results = await Promise.allSettled(urls.map(preload));
const images = results
  .filter((r) => r.status === 'fulfilled')
  .map((r) => r.value);

console.log(`${images.length} von ${urls.length} Bildern bereit`);
document.querySelector('.gallery').append(...images);
3 von 3 Bildern bereit

Auf ein Canvas zeichnen

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const img = new Image();
img.crossOrigin = 'anonymous'; // nötig, wenn das Canvas später ausgelesen werden soll
img.src = 'https://cdn.example.com/logo.png';

await img.decode();
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

// Wichtig · Fallstricke

  • Leeres oder ungültiges src: Ohne src, bei einem 404-Fehler oder einem kaputten Format wird das Promise mit EncodingError abgelehnt. Deshalb immer try/catch oder .catch() verwenden.
  • Kein dauerhafter Speicher-Cache: Browser können decodierte Pixeldaten wieder verwerfen, wenn das Bild nicht zeitnah ins DOM eingefügt wird. Deshalb nach dem Decodieren nicht unnötig lange mit dem Einfügen warten.
  • Wenn sich src ändert: Wird src oder srcset geändert, während decode() noch läuft, kann das ursprüngliche Promise abgelehnt werden. Warten Sie also erst auf das Promise, bevor Sie die Quelle erneut ändern.
  • srcset/sizes: Bei Bildern außerhalb des DOM wählt der Browser die Bildquelle unter Umständen ohne den späteren Layout-Kontext aus. Bei responsiven Bildern kann deshalb eine andere Auflösung geladen werden als erwartet.
  • Unterschied zum Attribut decoding="async": Das Attribut ist nur ein Hinweis an den Browser. Mit decode() dagegen erhalten Sie einen verlässlichen Zeitpunkt, an dem das Bild fertig ist.
  • Canvas und CORS: Bilder von fremden Domains ohne crossOrigin und passende CORS-Header machen das Canvas „tainted“. Danach schlagen getImageData() und toDataURL() fehl.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt, nicht aber vom Internet Explorer. Als Rückfalllösung dient das load-Event: 'decode' in img ? img.decode() : new Promise((res, rej) => { img.onload = res; img.onerror = rej; }).