Einleitung: Warum das Ändern der URL ohne Neuladen eine Superkraft ist
\n\nStellen Sie sich vor: Sie öffnen einen modernen Webdienst – sagen wir, einen E-Mail-Client oder einen Online-Dokumenteneditor. Sie wechseln zwischen Ordnern, öffnen E-Mails, ändern Einstellungen – und die Seite lädt nicht neu. Dabei ändert sich die Adressleiste des Browsers, die Schaltflächen „Zurück“ und „Vorwärts“ funktionieren, und Lesezeichen speichern den gewünschten Zustand. Wie funktioniert das? Die Magie der URL-Modifikation ohne Seitenneuladung.
\n\nDies ist nicht nur ein „Gimmick“ – es ist die Grundlage leistungsfähiger Single-Page-Anwendungen (SPA). Früher verwendeten Entwickler Hashes (#), aber das war unschön und unpraktisch. Heute haben wir die History API – ein mächtiges Werkzeug, mit dem wir URLs sofort ändern können, ohne Flackern, ohne Zustandsverlust, ohne unnötige HTTP-Anfragen.
\n\nIn diesem Artikel werden wir untersuchen, wie pushState und replaceState funktionieren, wie sie sich auf die Leistung auswirken und wie man bei der Optimierung nicht in die Falle tappt. Los geht's!
Grundlagen: Die History API und ihre Methoden
\n\nDie HTML5-Spezifikation hat uns die Schnittstelle window.history geschenkt. Die beiden wichtigsten Methoden zum Ändern der URL ohne Neuladen sind pushState und replaceState.
pushState – Einen neuen Eintrag zum Verlauf hinzufügen
\n\npushState erstellt einen neuen Eintrag im Browserverlauf. Der Benutzer kann auf „Zurück“ klicken und zur vorherigen URL zurückkehren.
// Syntax\nhistory.pushState(state, title, url);\n\n// Beispiel\nhistory.pushState({ page: 1 }, 'Startseite', '/home');\n\n\nParameter:
\n- \n
- state – Ein Datenobjekt, das mit diesem Eintrag verknüpft ist. Sie können beliebige serialisierbare Daten speichern (z. B. Filterzustand, Element-ID). \n
- title – Der Seitentitel (die meisten Browser ignorieren ihn, aber es ist besser, einen leeren String oder einen sinnvollen Text zu übergeben). \n
- url – Die neue URL. Sie muss relativ oder absolut sein, aber innerhalb desselben Ursprungs (Protokoll + Domain + Port). \n
replaceState – Den aktuellen Eintrag ersetzen
\n\nreplaceState ändert den aktuellen Eintrag im Verlauf, ohne einen neuen zu erstellen. Der Benutzer kann nicht „zurück“ zur vorherigen URL navigieren – sie wird ersetzt.
// Syntax\nhistory.replaceState(state, title, url);\n\n// Beispiel – URL bei Filteränderung aktualisieren\nfunction applyFilter(filterName) {\n history.replaceState({ filter: filterName }, '', `?filter=${filterName}`);\n updateUI(filterName);\n}\n\n\npopstate – Auf Verlaufsänderungen lauschen
\n\nWenn der Benutzer auf „Zurück“ oder „Vorwärts“ klickt, erzeugt der Browser das Ereignis popstate. Wichtig: pushState und replaceState lösen dieses Ereignis nicht aus – es muss separat behandelt werden.
window.addEventListener('popstate', function(event) {\n if (event.state) {\n // Zustand basierend auf den Daten aus event.state wiederherstellen\n restorePageState(event.state);\n } else {\n // Wenn state leer ist – möglicherweise hat der Benutzer den Bereich unserer Anwendung verlassen\n loadDefaultState();\n }\n});\n\n\nLeistungsoptimierung: Was wichtig zu wissen ist
\n\nDie URL-Modifikation ist schnell. Aber es gibt Nuancen, die eine Superkraft in eine Fehlerquelle verwandeln können.
\n\n1. Rufen Sie pushState nicht zu oft auf
\n\nJeder Aufruf von pushState fügt einen Eintrag zum Verlauf hinzu. Wenn Sie ihn bei jeder Mausbewegung oder jedem Zeichen in der Suche aufrufen, bläht sich der Verlauf auf, und der Benutzer muss 100 Mal auf „Zurück“ klicken, um den Filter zu verlassen. Verwenden Sie replaceState für Zwischenzustände und pushState für logisch abgeschlossene Aktionen (z. B. Öffnen einer neuen Seite).
2. Synchronisieren Sie den Zustand mit der URL
\n\nStellen Sie sicher, dass der Anwendungszustand immer mit der aktuellen URL übereinstimmt. Wenn ein Benutzer die Seite aktualisiert oder ein Lesezeichen verwendet, sollte die Anwendung den Zustand aus der URL wiederherstellen können. Verwenden Sie dazu die popstate-Ereignisbehandlung und initiale Zustandswiederherstellung beim Laden der Seite.