Tiefenblick

Die Geburt von WebP: Wie VP8 zum Bildformat wurde

koboshiCo-founder
·18 min Lesezeit
Die Geburt von WebP: Wie VP8 zum Bildformat wurde
Zusammenfassung

WebP ist ein RIFF-basierter Behälter, der VP8-Videoframes für Standbilder kapselt. Google stellte es 2010 mit dem kühnen Anspruch vor, 25-34 % kleinere Dateien als JPEG und PNG zu erzeugen. Hier ist die vollständige technische Geschichte, von der Dateisignatur bis zur Lücke in der realen Einführung.

Öffne eine WebP-Datei in einem Hex-Editor. Die ersten zwölf Bytes:

52 49 46 46 ?? ?? ?? ?? 57 45 42 50

Das ist der RIFF/WAVE-Behälter-Header. 52 49 46 46 buchstabiert "RIFF" in ASCII. Die nächsten vier Bytes sind die Dateigröße in Little-Endian uint32. 57 45 42 50 buchstabiert "WEBP". Eine WebP-Datei ist kein roher Bitstrom. Es ist ein Behälter, genau wie WAV-Audio oder AVI-Video, aufgebaut nach derselben RIFF-Spezifikation, die Microsoft 1991 einführte. Innerhalb dieses Behälters sitzt ein VP8-Videoframe, umgewidmet für ein Standbild. Diese Designentscheidung, einen Videocodec für Fotos zu verwenden, ist das wichtigste Detail, um WebP zu verstehen.

Google stellte WebP am 30. September 2010 vor. Die Verkaufsargumente waren simpel: dieselbe Bildqualität wie JPEG, aber 25-34 % kleinere Dateien. Für PNG war die Behauptung noch kühner, 26 % kleinere Dateien bei verlustfreien Bildern. In einem Web, in dem Bilddaten etwa die Hälfte aller übertragenen Daten ausmachen, hätten diese Zahlen eigentlich für eine Masseneinführung reichen müssen. Das passierte nicht.

Die Übernahme, die WebP schuf

WebP kam nicht aus einem Bildlabor. Es kam aus einem Videocodec.

Im Februar 2010 übernahm Google On2 Technologies für etwa 124 Millionen Dollar. On2 war ein Unternehmen für Videokompression mit langer Historie; ihre Codecs trieben Flash-Video, Skype-Videotelefonie und AOL-Streaming an. Ihr Flaggschiff war VP8, ein Videocodec, der entwickelt wurde, um mit H.264 zu konkurrieren, ohne Patentgebühren zu erheben.

Google veröffentlichte VP8 im Mai 2010 als Open Source unter dem Namen WebM, kombiniert mit dem Vorbis-Audio-Codec und dem Matroska-Behälter. Das Ziel war klar: einen patentfreien Videostack aufbauen, um dem H.264-Lizenzpool von MPEG-LA zu trotzen, der begann, Gebühren für Web-Video-Streaming zu verlangen.

Aber Google hatte einen zweiten Anwendungsfall im Kopf. Die Intra-Frame-Kompression von VP8, die Kompression eines einzelnen Videoframes ohne Bezug auf andere Frames, war im Grunde ein Standbild-Codec. Dieselben Prädiktionsmodi, Transformationscodierung und Entropiecodierung, die VP8 für Video effizient machten, funktionierten auch für Fotografien. Google extrahierte den Intra-Frame-Modus, kapselte ihn in einen RIFF-Behälter und nannte es WebP.

Der Name war eine Marketingentscheidung. "Web", weil es für das Web entwickelt wurde. "P", weil Bildformate auf P enden: JPEG, PNG, BMP, TIFF. Das Ergebnis war ein Format, das technisch gesehen ein Videoframe war, der vorgab, ein Foto zu sein.

Warum überhaupt ein neues Format entwickeln?

2010 war JPEG achtzehn Jahre alt und PNG vierzehn. Beide waren fest etabliert. Warum also die Mühe?

Die Einschränkungen von JPEG waren real und bekannt:

  • Keine Transparenz. Ein JPEG-Pixel ist entweder vollständig deckend, oder man braucht eine separate Maske.
  • Keine Animation. Animated JPEG existiert nicht als Standard.
  • Nur verlustbehaftet. Die Basisspezifikation von JPEG hat keinen verlustfreien Modus. (JPEG-LS und JPEG 2000 existieren, aber keines ist webkompatibel.)
  • 8-bit Farbtiefe pro Kanal. Kein Wide-Gamut- oder HDR-Support in der Basisspezifikation.
  • Blocking-Artefakte bei niedriger Qualität. Das 8 x 8 DCT-Raster ist bei Qualitätseinstellungen unter 75 sichtbar.

Die Einschränkungen von PNG waren ebenso real:

  • Kein verlustbehafteter Modus. PNG ist immer verlustfrei. Ein 12-MP-Foto als PNG ist 15-25 MB groß.
  • Große Dateien für Fotografien. Die DEFLATE-Kompression von PNG kann nicht mit DCT-basierter psycho-visueller Verwerfung konkurrieren.
  • Keine Animation in der Basisspezifikation. APNG existiert, brauchte aber Jahre, um Browser-Support zu erhalten.

Google erkannte eine Lücke: ein einziges Format, das verlustbehaftete und verlustfreie Kompression, Transparenz und Animation beherrscht, alles in kleineren Dateien als die etablierten Formate. Das war das Verkaufsargument von WebP.

Wie WebP tatsächlich funktioniert

WebP hat zwei fundamental unterschiedliche interne Formate: verlustbehaftetes WebP (VP8 Intra-Frame) und verlustfreies WebP (ein separater Codec, ebenfalls aus VP8-Forschung abgeleitet).

Verlustbehaftetes WebP: VP8 Intra

Verlustbehaftetes WebP speichert einen VP8-Bitstrom innerhalb eines RIFF-Behälters. Die Encodierungspipeline ist konzeptionell ähnlich wie bei JPEG, aber mit wichtigen Unterschieden:

PhaseJPEGVerlustbehaftetes WebP
Transformation8 x 8 DCT4 x 4 oder 16 x 16 integer DCT-like transform
PrädiktionKeine (nur Intra)4 Intra-Prädiktionsmodi pro 4 x 4 Block
Chroma subsampling4:2:0 default4:2:0 default
EntropiecodierungHuffmanBinary arithmetic coding
Farbtiefe8-bit8-bit

Die intra prediction ist der größte Gewinn. JPEG kodiert jeden 8 x 8 Block unabhängig. WebP prädiziert jeden 4 x 4 Block von seinen bereits kodierten Nachbarn (oben, links oder beides) und kodiert dann nur den Prädiktionsfehler. Für sanfte Gradienten und große flache Bereiche ist der Fehler winzig, und das Kompressionsverhältnis verbessert sich erheblich.

Der arithmetische Kodierer ist außerdem effizienter als die Huffman-Codierung von JPEG. Das bringt typischerweise 5-10 % zusätzliche Einsparungen bei gleicher Qualität.

Googles eigene Benchmarks von 2010 behaupteten:

MetrikWebP vs JPEG
Durchschnittliche Dateigrößenreduktion25-34 % bei gleichem SSIM
Encodiergeschwindigkeit~8x langsamer als libjpeg
DecodiergeschwindigkeitVergleichbar mit libjpeg

Die Encodiergeschwindigkeit war die versteckte Kostenstelle. Eine WebP-Datei zu erzeugen, erforderte deutlich mehr CPU als JPEG. Für Fotografen, die Hunderte von Bildern exportieren, machte das einen Unterschied.

Verlustfreies WebP

Verlustfreies WebP verwendet einen komplett anderen Codec. Es ist nicht VP8. Es ist ein benutzerdefiniertes Format, das folgendes kombiniert: prädiktive Codierung mit 14 verschiedenen räumlichen Prädiktionsmodi pro Pixel, einen Color Cache als Hash-Tabelle kürzlich gesehener Farben, LZ77-Back-References ähnlich wie PNGs DEFLATE aber mit 2D-räumlich-bewusstem Matching und einen Huffman- und Arithmetik-Hybrid für die Entropiecodierung.

Google behauptete durchschnittlich 26 % kleinere Dateien als PNG. In der Praxis variieren die Einsparungen stark. Einfache Grafiken mit großen flachen Bereichen profitieren kaum, während Fotos mit feiner Textur 30-40 % Reduktion erreichen können.

Erweitertes WebP (VP8X)

Der VP8X-Chunk erweitert WebP um zusätzliche Funktionen:

  • Alpha-Channel: 8-bit Alpha, separat encodiert, komprimiert mit dem Entropie-Coder von verlustfreiem WebP.
  • Animation: Mehrere Frames mit Timing-Metadaten, im Grunde ein abgespecktes VP8-Video.
  • EXIF-Metadaten: Kamera- und Geolokalisierungsdaten.
  • XMP-Metadaten: Adobe-artige Verarbeitungsanweisungen.
  • ICC-Farbprofil: Wide-Gamut- und HDR-Farbmanagement.

Eine VP8X-Datei beginnt mit einem VP8X-Chunk-Header, gefolgt von Flags, die anzeigen, welche Erweiterungen vorhanden sind.

Das Dateiformat

WebP ist ein RIFF-Behälter. Das Bytelayout zu verstehen ist simpel, wenn man RIFF kennt.

RIFF-Behälter-Struktur

Bytes 0-3:   "RIFF" (0x52 0x49 0x46 0x46)
Bytes 4-7:   Dateigröße - 8 (Little-Endian uint32)
Bytes 8-11:  "WEBP" (0x57 0x45 0x42 0x50)
Bytes 12-15: Chunk FourCC - "VP8 ", "VP8L" oder "VP8X"
Bytes 16-19: Chunk-Größe (Little-Endian uint32)
Bytes 20+:   Chunk-Daten

VP8X extended header

Wenn der FourCC bei Bytes 12-15 "VP8X" (0x56 0x50 0x38 0x58) ist:

Bytes 20-23: Chunk-Größe = 10 (Little-Endian uint32)
Bytes 24:    Flags-Byte
             Bit 0: Animation vorhanden
             Bit 1: XMP-Metadaten vorhanden
             Bit 2: EXIF-Metadaten vorhanden
             Bit 3: Alpha channel vorhanden
             Bit 4: ICC-Profil vorhanden
             Bits 5-7: Reserviert
Bytes 25-27: Canvas-Breite - 1 (Little-Endian uint24)
Bytes 28-30: Canvas-Höhe - 1 (Little-Endian uint24)

Die Canvas-Dimensionen werden als Breite - 1 und Höhe - 1 gespeichert, also speichert ein 1200 x 675 Bild 1199 und 674. Die maximale Canvas-Größe beträgt 16.777.215 x 16.777.215 Pixel.

Chunk-Typen

FourCCInhaltKompression
VP8 VP8-Bitstrom (verlustbehaftet)VP8 intra
VP8LVP8L-Bitstrom (verlustfrei)Custom lossless
VP8XErweiterter Header + FlagsKeine
ALPHAlpha-Channel-DatenVerlustfreie WebP-Entropie
ANMFAnimationsframeVP8/VP8L pro Frame
ICCPICC-FarbprofilKeine
EXIFEXIF-MetadatenKeine
XMP XMP-MetadatenKeine

WebP anhand der Dateisignatur erkennen

Vertraue nicht der .webp-Erweiterung. Lies die ersten 16 Bytes und parste den RIFF-Header.

Exaktes Bytelayout einer einfachen verlustbehafteten WebP-Datei:

Bytes 0-3:   "RIFF"
Bytes 4-7:   Dateigröße (Little-Endian uint32)
Bytes 8-11:  "WEBP"
Bytes 12-15: "VP8 " (lossy) oder "VP8L" (lossless) oder "VP8X" (extended)

TypeScript im Browser:

interface WebPInfo {
  valid: boolean
  type: "lossy" | "lossless" | "extended" | "unknown"
  width?: number
  height?: number
  hasAlpha?: boolean
  isAnimated?: boolean
}

async function inspectWebP(file: File): Promise<WebPInfo> {
  const buffer = await file.slice(0, 30).arrayBuffer()
  const bytes = new Uint8Array(buffer)

  if (bytes.length < 12) return { valid: false, type: "unknown" }

  const riff = String.fromCharCode(...bytes.slice(0, 4))
  const webp = String.fromCharCode(...bytes.slice(8, 12))
  if (riff !== "RIFF" || webp !== "WEBP") {
    return { valid: false, type: "unknown" }
  }

  const type = String.fromCharCode(...bytes.slice(12, 16))

  if (type === "VP8 ") {
    // Lossy: Breite/Höhe bei Bytes 26-29
    const w = bytes[26] | (bytes[27] << 8)
    const h = bytes[28] | (bytes[29] << 8)
    return { valid: true, type: "lossy", width: w, height: h, hasAlpha: false }
  }

  if (type === "VP8L") {
    // Lossless: Dimensionen in Bits von Bytes 21-24 gepackt
    const bits =
      bytes[21] | (bytes[22] << 8) | (bytes[23] << 16) | (bytes[24] << 24)
    const w = (bits & 0x3fff) + 1
    const h = ((bits >> 14) & 0x3fff) + 1
    const alpha = ((bits >> 28) & 0x01) !== 0
    return {
      valid: true,
      type: "lossless",
      width: w,
      height: h,
      hasAlpha: alpha,
    }
  }

  if (type === "VP8X") {
    const flags = bytes[20]
    const w = (bytes[24] | (bytes[25] << 8) | (bytes[26] << 16)) + 1
    const h = (bytes[27] | (bytes[28] << 8) | (bytes[29] << 16)) + 1
    return {
      valid: true,
      type: "extended",
      width: w,
      height: h,
      hasAlpha: (flags & 0x10) !== 0,
      isAnimated: (flags & 0x02) !== 0,
    }
  }

  return { valid: false, type: "unknown" }
}

Python

import struct
from typing import TypedDict

class WebPInfo(TypedDict):
    valid: bool
    type: str
    width: int | None
    height: int | None
    has_alpha: bool | None
    is_animated: bool | None

def inspect_webp(path: str) -> WebPInfo:
    with open(path, "rb") as f:
        header = f.read(30)

    if len(header) < 12:
        return {"valid": False, "type": "unknown"}

    if header[:4] != b"RIFF" or header[8:12] != b"WEBP":
        return {"valid": False, "type": "unknown"}

    chunk_type = header[12:16]

    if chunk_type == b"VP8 ":
        w, h = struct.unpack("<HH", header[26:30])
        return {"valid": True, "type": "lossy", "width": w, "height": h,
                "has_alpha": False, "is_animated": None}

    if chunk_type == b"VP8L":
        bits = struct.unpack("<I", header[21:25])[0]
        w = (bits & 0x3FFF) + 1
        h = ((bits >> 14) & 0x3FFF) + 1
        alpha = ((bits >> 28) & 0x01) != 0
        return {"valid": True, "type": "lossless", "width": w, "height": h,
                "has_alpha": alpha, "is_animated": None}

    if chunk_type == b"VP8X":
        flags = header[20]
        w = struct.unpack("<I", header[24:27] + b"\x00")[0] + 1
        h = struct.unpack("<I", header[27:30] + b"\x00")[0] + 1
        return {"valid": True, "type": "extended", "width": w, "height": h,
                "has_alpha": bool(flags & 0x10), "is_animated": bool(flags & 0x02)}

    return {"valid": False, "type": "unknown"}

High-Level-Option mit Pillow:

from PIL import Image

with Image.open("image.webp") as img:
    print(img.format)      # WEBP
    print(img.mode)        # RGB oder RGBA
    print(img.size)        # (Breite, Höhe)
    print(img.is_animated) # True, wenn animiert

Oder mit der webp-Bibliothek:

import webp

info = webp.WebPInfo("image.webp")
print(info.width, info.height, info.has_alpha)

Go

package main

import (
	"encoding/binary"
	"fmt"
	"os"
)

type WebPInfo struct {
	Valid       bool
	Type        string
	Width       int
	Height      int
	HasAlpha    bool
	IsAnimated  bool
}

func inspectWebP(path string) (WebPInfo, error) {
	f, err := os.Open(path)
	if err != nil {
		return WebPInfo{}, err
	}
	defer f.Close()

	buf := make([]byte, 30)
	if _, err := f.Read(buf); err != nil {
		return WebPInfo{}, err
	}

	if string(buf[:4]) != "RIFF" || string(buf[8:12]) != "WEBP" {
		return WebPInfo{Valid: false, Type: "unknown"}, nil
	}

	typeStr := string(buf[12:16])
	switch typeStr {
	case "VP8 ":
		w := int(binary.LittleEndian.Uint16(buf[26:28]))
		h := int(binary.LittleEndian.Uint16(buf[28:30]))
		return WebPInfo{Valid: true, Type: "lossy", Width: w, Height: h, HasAlpha: false}, nil
	case "VP8L":
		bits := binary.LittleEndian.Uint32(buf[21:25])
		w := int(bits&0x3FFF) + 1
		h := int((bits>>14)&0x3FFF) + 1
		alpha := ((bits >> 28) & 0x01) != 0
		return WebPInfo{Valid: true, Type: "lossless", Width: w, Height: h, HasAlpha: alpha}, nil
	case "VP8X":
		flags := buf[20]
		w := int(binary.LittleEndian.Uint32(append(buf[24:27], 0))) + 1
		h := int(binary.LittleEndian.Uint32(append(buf[27:30], 0))) + 1
		return WebPInfo{
			Valid: true, Type: "extended", Width: w, Height: h,
			HasAlpha: (flags & 0x10) != 0, IsAnimated: (flags & 0x02) != 0,
		}, nil
	}

	return WebPInfo{Valid: false, Type: "unknown"}, nil
}

PHP

function inspectWebP(string $path): array {
    $header = file_get_contents($path, false, null, 0, 30);
    if (strlen($header) < 12) {
        return ["valid" => false, "type" => "unknown"];
    }

    if (substr($header, 0, 4) !== "RIFF" || substr($header, 8, 4) !== "WEBP") {
        return ["valid" => false, "type" => "unknown"];
    }

    $type = substr($header, 12, 4);

    if ($type === "VP8 ") {
        $w = unpack("v", substr($header, 26, 2))[1];
        $h = unpack("v", substr($header, 28, 2))[1];
        return ["valid" => true, "type" => "lossy", "width" => $w, "height" => $h, "has_alpha" => false];
    }

    if ($type === "VP8L") {
        $bits = unpack("V", substr($header, 21, 4))[1];
        $w = ($bits & 0x3FFF) + 1;
        $h = (($bits >> 14) & 0x3FFF) + 1;
        $alpha = (($bits >> 28) & 0x01) !== 0;
        return ["valid" => true, "type" => "lossless", "width" => $w, "height" => $h, "has_alpha" => $alpha];
    }

    if ($type === "VP8X") {
        $flags = ord($header[20]);
        $w = unpack("V", substr($header, 24, 3) . "\x00")[1] + 1;
        $h = unpack("V", substr($header, 27, 3) . "\x00")[1] + 1;
        return [
            "valid" => true, "type" => "extended",
            "width" => $w, "height" => $h,
            "has_alpha" => (bool)($flags & 0x10),
            "is_animated" => (bool)($flags & 0x02),
        ];
    }

    return ["valid" => false, "type" => "unknown"];
}

Mit fileinfo:

$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file('image.webp');
// image/webp

ImageMagick CLI

magick identify -verbose image.webp | grep "Format:"
# Format: WEBP (WebP Image Format)

Vollständige Metadaten-Extraktion:

magick identify -verbose image.webp

Das gibt Breite, Höhe, Farbtiefe, Alpha-Vorhandensein, Kompressionstyp und ICC-Profil-Informationen aus.

Oder einfach:

file image.webp
# image.webp: RIFF (little-endian) data, Web/P image

Die Stärken

Der offensichtlichste Vorteil ist die Dateigröße. In Googles Referenzkorpus waren verlustbehaftete WebP-Dateien im Durchschnitt 25-34 % kleiner als JPEG bei gleichem SSIM, verlustfreie WebP-Dateien durchschnittlich 26 % kleiner als PNG. Für High-Traffic-Seiten übersetzen sich diese Einsparungen direkt in Bandbreitenkosten und schnellere Ladezeiten.

Ein weiterer Pluspunkt ist die Konsolidierung der Features. Ein Format ersetzt JPEG und PNG für die meisten Anwendungsfälle: verlustbehafteter Modus für Fotos, verlustfreier Modus für Grafiken, Alpha-Channel für Transparenz, Animation für kurze Sequenzen. Ein Web-Entwickler muss ein Format statt drei kennen.

Browser decodieren WebP nativ. Chrome, Firefox, Safari und Edge liefern alle hardwarebeschleunigte oder hochoptimierte softwareseitige WebP-Decoder. Die Decodiergeschwindigkeit ist auf dem Desktop vergleichbar mit JPEG und auf Mobilgeräten nur 10-20 % langsamer.

WebP unterstützt progressive Decodierung, also inkrementelle Anzeige während Daten eintreffen, ähnlich wie der progressive Modus von JPEG. Für langsame Verbindungen erscheint ein erkennbares Bild nach Empfang von etwa 30 % der Datei.

Bei Animation sind WebP-Dateien typischerweise 60-80 % kleiner als animierte GIFs bei gleicher Bildqualität, mit vollem 24-bit-Farbraum und 8-bit Alpha pro Frame.

Die Schwächen

WebPs Probleme sind nicht technischer Natur, sondern ökologisch.

Die Encodiergeschwindigkeit war schon immer ein Nachteil. 2010 war die WebP-Encodierung etwa 8-mal langsamer als libjpeg. Die Lücke hat sich verringert, libwebp 2026 ist etwa 2-3-mal langsamer als libjpeg-turbo, aber für Batch-Workflows zählt das immer noch. Ein Fotograf, der 1.000 Bilder exportiert, wartet merklich länger.

WebP ist strikt 8-bit pro Kanal und hat damit keinen 16-bit- oder HDR-Support. Für Wide-Gamut-Fotografie, medizinische Bildgebung oder HDR-Inhalte ist WebP unbrauchbar. HEIC, AVIF und JPEG XL unterstützen alle höhere Bittiefen.

Es gibt auch keine verlustfreie JPEG-Rekompression. JPEG XL kann ein bestehendes JPEG verlustfrei rekomprimieren für etwa 20 % Einsparungen. WebP kann das nicht. Die Konvertierung von JPEG zu WebP erfordert eine vollständige Neuencodierung, die Generation Loss einführt.

Das Tooling hinkte lange hinterher. Photoshop unterstützte WebP nicht nativ bis 2022. ImageMagicks WebP-Support erforderte eine libwebp-Plugin-Kompilierung, die viele Distributionen standardmäßig wegließen. Viele Content-Management-Systeme generieren immer noch standardmäßig JPEG/PNG.

Über VP8 hing außerdem eine Patentwolke. Google veröffentlichte den Codec mit einem Patent-Entschädigungsversprechen, aber die Patentlandschaft war nie so sauber wie die von PNG oder JPEG. Einige Organisationen vermieden WebP gezielt, weil sie Googles rechtlichen Schutzschild nicht für gerichtsfest hielten.

Warum das "inferiore" Format gewann

JPEG ist vierunddreißig Jahre alt. Es hat keine Transparenz, keine Animation, keinen verlustfreien Modus und sichtbare Artefakte bei Qualität 75. WebP schlägt es in fast jeder Metrik. Trotzdem gibt der Web Almanac 2025 JPEG mit etwa 46 % aller Web-Bilder gegenüber WebP mit 19 % an.

Der Grund sind Netzwerkeffekte und Wechselkosten, nicht technische Mängel.

JPEG ist das QWERTY der Bildformate. Kameras speichern standardmäßig JPEG, Telefone zeigen es nativ an, Drucker akzeptieren es. Soziale Netzwerke, CMS, CDNs und E-Mail-Clients verarbeiten JPEG ohne Plugins, Codecs oder Konvertierung. Das Format ist so universell, dass "Bild" und "JPEG" für die meisten Nutzer funktional synonym sind.

WebPs Einführungskurve erzählt die Geschichte:

JahrMeilenstein
2010Google kündigt WebP an (Chrome 8)
2012Chrome 23 fügt lossless- und Alpha-Support hinzu
2013Chrome fügt animated WebP hinzu
2014Android 4.0+ fügt nativen WebP-Support hinzu
2015Facebook konvertiert alle mobilen Fotos zu WebP
2016Safari 14 fügt WebP-Support hinzu
2020Universeller Browser-Support erreicht
2022Photoshop fügt nativen WebP-Export hinzu
2025WebP bei 19 % der Web-Bilder laut Web Almanac

Chrome trieb WebP aggressiv voran, weil Google sowohl den Browser als auch das Format kontrollierte. Facebook adoptierte es, weil es Petabytes an Bandbreite sparte. Aber der Long Tail des Webs (WordPress-Blogs, kleine E-Commerce-Seiten, Enterprise-CMS-Deployments, E-Mail-Newsletter) bewegte sich langsam oder gar nicht.

Entscheidend war Apples Ökosystem. iPhones speicherten standardmäßig HEIC, nicht WebP. macOS Preview unterstützte WebP erst ab macOS 11 Big Sur (2020). Das iOS-Share-Sheet bot keinen WebP-Export. Für Fotografen, Designer und Social-Media-Creator, die hauptsächlich auf Apple-Geräten arbeiteten, war WebP unsichtbar.

Inzwischen kam AVIF 2019 mit besserer Kompression als WebP und lizenzfreier Lizenzierung von der Alliance for Open Media. Chrome, Firefox und Safari liefern alle AVIF. Cloudflare und Cloudinary servieren AVIF automatisch. WebP wurde zu einem Sprungbrett, besser als JPEG, aber bereits von der nächsten Generation überholt.

Wo WebP heute steht

WebP ist kein Fehlschlag, sondern ein Teilerfolg.

Für Web-Entwickler, die 2026 neue Projekte aufbauen, ist WebP die pragmatische Standardwahl für Bilder, die Transparenz oder Animation benötigen. Es ist kleiner als PNG für verlustfreie Grafiken und kleiner als JPEG für Fotografien. Der Browser-Support ist universell. Das Encode-Tooling ist ausgereift.

Aber WebP hat JPEG nicht abgelöst. Es hat sich eine Nische daneben herausgeschnitten, dieselbe Nische, die PNG bereits innehatte, nur mit kleineren Dateien. Die Vision von "ein Format für alle Bilder" materialisierte sich nicht.

Die praktische Realität für 2026:

AnwendungsfallBestes FormatWarum
Fotografien (Legacy)JPEGUniversell, schnelles Encoding, klein genug
Fotografien (neu)AVIF30 % kleiner als WebP, lizenzfrei
Fotografien (Fallback)WebP25 % kleiner als JPEG, universeller Support
Verlustfreie GrafikenWebP oder PNGWebP ist kleiner; PNG ist der sichere Fallback
TransparenzWebP oder PNGWebP hat kleinere Dateien; PNG ist der sichere Fallback
AnimationWebP oder AVIFBeide schlagen GIF um 60-80 %; AVIF ist neuer
Wide-Gamut / HDRAVIF oder JPEG XL10+ bit depth, ICC/ICC v4-Support
Print-WorkflowsTIFF oder JPEG XLCMYK, 16-bit, verlustfreie JPEG-Rekompression

WebPs wirkliches Erbe ist die Erkenntnis, dass das Web neue Bildformate akzeptiert, wenn ein großer Browser-Anbieter genug Druck macht. Chrome und Google haben bewiesen, dass ein Format sich durchsetzen kann. Apple musste daraufhin nicht-JPEG/PNG-Formate nativ unterstützen, und die Branche hat gesehen, dass Transparenz und Animation in einem einzigen Behälter funktionieren.

Aber das Format hat auch gezeigt, dass technische Vorteile allein nicht reichen. Allgegenwart, Trägheit und die Bindung an bestehende Ökosysteme wiegen schwerer als Kompressionsraten. JPEG wird WebP wahrscheinlich überleben, nicht weil es besser ist, sondern weil es schon überall ist.

Was bleibt

WebP wurde aus einem Videocodec entwickelt, um ein Bandbreitenproblem zu lösen. Für Google, Facebook und jede Seite, die ihre Bildpipeline umstellte, hat es das auch getan. Die Kompression ist real, die Features sind nützlich, und der Browser-Support ist vollständig.

Aber das Web wechselt nicht das Format, bloß weil ein Whitepaper behauptet, das neue sei 25 % kleiner. Es wechselt, wenn das neue Format einfacher zu nutzen ist als das alte, oder wenn das alte so schlecht versagt, dass Umstieg nötig wird. JPEG hat nie schlecht genug versagt, WebP war nie einfach genug, und als WebP endlich einfach war, kam AVIF mit einer besseren Zahl im Datenblatt.

WebP ist das Betamax der Bildformate: technisch solide, gut unterstützt, aber von etwas überholt, das etwas später mit besserem Marketing und breiterer Unterstützung ankam. Es wird nicht verschwinden, sondern neben JPEG, PNG, AVIF und was als Nächstes kommt koexistieren. Dabei erfüllt es dieselbe Rolle, die PNG heute spielt: der sichere, fähige Fallback, der überall funktioniert.

Wenn du PNG-Dateien hast, die kleinere Dateigrößen für das Web brauchen, konvertiert PNG to WebP sie lokal im Browser, ohne Uploads und ohne Serververarbeitung. Für JPEGs, die Transparenz oder Animation benötigen, übernimmt JPG to WebP die Konvertierung mit Qualitätskontrolle. Und wenn du den universellen Fallback brauchst, bringen WebP to PNG und WebP to JPG WebP-Dateien zurück in Formate, die in jedem Viewer geöffnet werden.

Mehr Blog-Posts zum Lesen