Viele Performance-Probleme im Web entstehen nicht durch „zu langsame Server“, sondern durch unnötige Wiederholungen: Der Browser lädt dieselben Dateien immer wieder, obwohl sie sich gar nicht geändert haben. Genau hier helfen Conditional Requests (bedingte Anfragen). Sie sorgen dafür, dass der Server sagen kann: „Du hast schon die aktuelle Version – nutze deinen Cache weiter.“
Das spart Bandbreite, reduziert Serverlast und macht Seiten schneller – ohne dass Inhalte veralten. Im Zentrum stehen dabei Conditional Requests, der ETag-Header, die Anfrage mit If-None-Match und die Antwort 304 Not Modified. Klingt technisch, ist aber mit einem klaren Ablauf leicht zu verstehen.
Was bedingte Anfragen leisten – und was nicht
Der Unterschied: „frisch aus Cache“ vs. „kurz nachfragen“
Beim Caching gibt es zwei grundsätzliche Strategien:
- Frische-Caching: Der Browser darf eine Datei für eine bestimmte Zeit ohne Rückfrage verwenden (z. B. über Cache-Control). Das ist schnell, aber Änderungen werden erst nach Ablauf sichtbar.
- Revalidierung: Der Browser fragt kurz beim Server nach, ob seine Kopie noch gĂĽltig ist. Wenn ja, wird nichts neu ĂĽbertragen.
Conditional Requests gehören zur Revalidierung. Sie sind besonders hilfreich, wenn Inhalte sich gelegentlich ändern, aber nicht ständig: Produktbilder, gebündelte CSS/JS-Dateien, HTML-Seiten, API-Responses, die nicht bei jedem Request anders sind.
Wann Conditional Requests weniger sinnvoll sind
Wenn eine Ressource praktisch bei jedem Abruf anders ist (z. B. personalisierte HTML-Seiten, ständig wechselnde Echtzeit-Daten), bringt Revalidierung wenig. Auch bei sehr kurzen Cache-Zeiten ist der Effekt begrenzt, weil ohnehin häufig neu validiert wird. Dann lohnt eher eine saubere Cache-Strategie oder eine andere API-Aufteilung.
ETag, If-None-Match und 304: der Ablauf in Alltagssprache
ETag als „Fingerabdruck“ einer Ressource
Ein ETag ist eine Art Kennzeichen für eine konkrete Version einer Ressource. Der Server sendet ihn in der Antwort mit. Beispiel: Der Browser lädt /app.css. Der Server antwortet mit Inhalt plus ETag, der diese Version beschreibt.
Beim nächsten Abruf muss der Browser die Datei nicht blind erneut herunterladen. Stattdessen sendet er eine bedingte Anfrage: „Ich habe Version X – ist das noch aktuell?“ Das macht er über If-None-Match (das Feld enthält den ETag, den der Browser gespeichert hat).
304 Not Modified: Inhalt bleibt beim Browser
Wenn der Server erkennt, dass sich die Ressource seitdem nicht geändert hat, kommt die Antwort 304 Not Modified. Diese Antwort enthält typischerweise keinen Body (keinen Inhalt). Der Browser nutzt dann seine lokale Kopie. Ergebnis: fast keine Datenübertragung, aber trotzdem die Sicherheit, dass nichts veraltet ist.
Wenn sich etwas geändert hat
Hat sich die Ressource verändert, antwortet der Server normal mit Status 200 und liefert den neuen Inhalt plus neuen ETag. Der Browser ersetzt seine Kopie im Cache.
Starke und schwache ETags: was dahinter steckt
Starker ETag: exakt gleiche Bytes
Ein starker ETag sagt: Wenn der ETag gleich ist, dann ist der Inhalt bytegenau identisch. Das ist ideal, wenn Clients genau dieselbe Datei behalten sollen.
Schwacher ETag: inhaltlich gleich, aber nicht bitgenau
Ein schwacher ETag (oft mit W/ markiert) bedeutet: Die Ressource ist „inhaltlich gleich genug“, auch wenn die Bytes minimal abweichen könnten (z. B. andere Kompression). Das kann sinnvoll sein, wenn die genaue Byte-Identität nicht entscheidend ist, aber die semantische Gleichheit schon.
Wichtig ist vor allem: ETag ist nicht „Magie“, sondern nur ein Vergleichswert. Der Server muss ihn konsistent erzeugen – sonst verpufft der Nutzen.
So wird es in der Praxis umgesetzt: Backend, Proxy, Browser
ETag erzeugen: typische Strategien
Ein ETag kann zum Beispiel aus einer Version, einem Hash des Inhalts oder einem Zeitstempel abgeleitet werden. Welche Strategie passt, hängt davon ab, wie die Ressource entsteht:
- Statische Dateien (CSS/JS/Images): ETag aus Dateihash oder Build-Hash.
- HTML-Seiten: ETag aus Template-Version plus relevanten Datenständen (vorsichtig bei Personalisierung).
- API-Responses: ETag aus einer Ressourcen-Version (z. B. „letzte Änderung“) oder einem Hash des JSON.
Bei dynamischen Antworten ist eine Hash-Bildung über den kompletten Response manchmal zu teuer. Dann ist eine Versionierung pro Datensatz (z. B. „updated_at“ als Grundlage) oft besser.
Zusammenspiel mit Cache-Control
Conditional Requests ersetzen Cache-Control nicht. Beides ergänzt sich: Cache-Control steuert, ob der Browser ohne Nachfrage verwenden darf. Conditional Requests regeln, wie diese Nachfrage aussieht, wenn sie nötig ist. Wer HTTP-Caching tiefer sortieren will, findet eine gute Ergänzung in HTTP Caching: Cache-Control und ETag richtig nutzen.
Typische Stolperfallen in Setups mit CDN oder Reverse Proxy
In vielen Umgebungen sitzt zwischen Browser und Backend ein CDN oder Reverse Proxy. Das ist grundsätzlich gut, kann aber ETags verwirren:
- Der Proxy komprimiert Inhalte oder verändert Header – dann kann ein starker ETag vom Ursprung nicht mehr passen.
- Mehrere Server erzeugen unterschiedliche ETags fĂĽr denselben Inhalt (z. B. weil der ETag aus lokalen Dateipfaden oder Instanz-IDs gebaut wird).
- Konfigurationen deaktivieren ETags für bestimmte Antworten (häufig bei großen Dateien oder Streaming).
In solchen Fällen hilft es, ETags „build-basiert“ (gleich für alle Instanzen) oder über das CDN zu definieren, statt sie pro Server dynamisch zu erzeugen.
Mini-Fallbeispiel: Wenn 304 plötzlich ausbleibt
Symptom: Browser lädt immer 200, obwohl sich nichts ändert
Ein häufiger Effekt: Die Datei app.js wird bei jedem Reload mit Status 200 geladen. In den DevTools ist zu sehen, dass zwar ein ETag kommt, aber beim nächsten Request kein If-None-Match gesendet wird – oder der Server trotzdem 200 antwortet.
Ursachen, die in der Praxis oft dahinter stecken
- Cache-Control verbietet Caching (z. B.
no-store). Dann speichert der Browser den ETag nicht dauerhaft. - Die URL wechselt ständig durch Query-Parameter (z. B.
?t=timestamp). Dann ist es aus Sicht des Browsers jedes Mal eine neue Ressource. - Der Server generiert ETags nicht deterministisch (z. B. enthält der ETag eine Request-ID oder Serverzeit).
Hier hilft ein klarer Blick in die Netzwerk-Ansicht: Werden ETag und If-None-Match wirklich ĂĽbertragen? Kommt 304? Oder verhindert eine Cache-Regel die Wiederverwendung?
Praktische Schritte, um Conditional Requests sauber zu nutzen
Kurze Umsetzungs-Notizen fĂĽr den Alltag
- In den Browser-DevTools prĂĽfen: Erste Antwort hat ETag? Folgerequest sendet If-None-Match? Antwort ist 304?
- URLs stabil halten: Keine zufälligen Query-Parameter für Versionierung. Besser: Dateinamen mit Build-Hash (z. B.
app.abc123.js). - ETags konsistent machen: Wenn mehrere Instanzen ausliefern, dürfen ETags nicht „serverabhängig“ sein.
- Revalidierung bewusst erlauben: Cache-Control so setzen, dass Caches gespeichert und bei Bedarf validiert werden können.
- FĂĽr APIs entscheiden, ob ETag wirklich passt: Bei stark personalisierten Responses ist es oft besser, ETags nur fĂĽr echte Ressourcen (z. B.
/users/123) zu nutzen.
Entscheidungshilfe: ETag oder lieber Versionierung im Dateinamen?
Vor- und Nachteile im direkten Vergleich
| Ansatz | Vorteile | Nachteile |
|---|---|---|
| ETag + 304 (Revalidierung) | Spart Transfer, bleibt korrekt aktuell, gut für seltene Änderungen | Zusätzlicher Roundtrip zur Validierung, ETag-Konsistenz nötig |
| Dateiname mit Hash (z. B. app.xyz.js) | Browser kann lange cachen, kein Revalidierungs-Request nötig | Build/Deployment muss saubere Hashes erzeugen, HTML muss neue Namen referenzieren |
| Beides kombiniert | Sehr robust: lange Cache-Zeit + sichere Aktualisierung bei HTML/API | Mehr Regeln, mehr Stellen zum PrĂĽfen |
Für typische Webapps ist Hash-Versionierung bei statischen Assets oft die stabilste Basis. Für HTML und APIs sind ETags und Conditional Requests dagegen häufig die bessere Wahl, weil sich Inhalte nicht so einfach über Dateinamen versionieren lassen.
Wie das zu anderen HTTP-Themen passt
Statuscodes und Cache-Strategie zusammen denken
304 ist ein Statuscode mit einer klaren Bedeutung: „Du darfst deine Kopie weiterverwenden.“ Wer Statuscodes grundsätzlich sicher einsetzen möchte, kann das Thema vertiefen über HTTP Statuscodes verstehen – Fehler sauber behandeln. Das hilft auch bei APIs, weil Caching und Fehlerbehandlung oft zusammen auftreten.
Logs helfen beim Debugging von Caching-Problemen
Wenn unklar ist, warum 304 nicht greift, lohnt ein Blick ins Backend-Logging: Wird If-None-Match an der richtigen Stelle ausgewertet? Werden Header durch Proxies entfernt? Sauber strukturierte Logs machen solche Fragen schneller beantwortbar, zum Beispiel mit dem Ansatz aus Structured Logging – Logs im Backend sinnvoll strukturieren.
Häufige Fragen aus der Praxis
Warum ist 304 manchmal langsamer als gedacht?
304 spart Daten, aber nicht unbedingt Zeit. Es bleibt ein zusätzlicher Request nötig. Bei sehr schnellen Assets oder bei hoher Latenz kann ein „frisch aus Cache ohne Nachfrage“ schneller sein. Deshalb lohnt sich bei statischen Dateien oft eine längere Cache-Zeit plus Hash im Dateinamen.
Kann ein ETag Sicherheitsprobleme verursachen?
ETags sind grundsätzlich harmlos, solange sie keine sensiblen Informationen enthalten. Problematisch wird es, wenn ein ETag z. B. interne IDs oder Nutzerbezug verrät. Daher sollten ETags wie technische Versionen wirken, nicht wie „Debug-Ausgaben“.
Was ist der Unterschied zu If-Modified-Since?
If-Modified-Since arbeitet mit Zeitstempeln (Last-Modified) statt mit einem Fingerabdruck. Zeitstempel können bei schnellen Änderungen oder bei Rundungsproblemen ungenauer sein. ETags sind oft präziser, erfordern aber eine saubere Erzeugung im Backend.

