Veröffentlicht: 28. August 2025
Die Google Suche hat eine der größten Reichweiten weltweit. Änderungen an der Benutzeroberfläche können sich daher auf Milliarden von Nutzern auswirken. Wir haben schon lange von einer Weboberfläche geträumt, die sich moderner und app-ähnlicher anfühlt. Als wir mit der Entwicklung des KI‑Modus begannen, wollten wir eine Funktion für unsere Nutzer schaffen, bei der der Übergang von der Standardsuche in den KI‑Modus nahtlos und verbunden ist. Als wir von Dokumentübergängen hörten, wussten wir, dass sie sich perfekt für diese Funktion eignen. In dieser Fallstudie erfahren Sie, was wir beim Hinzufügen der Übergangsfunktion im Rahmen der Einführung des KI‑Modus gelernt haben.
Dokumentübergreifende Ansichtsübergänge sind ein echter Gamechanger für native Browser-Tools und wir sind gespannt, wie sie das Web in Zukunft prägen werden.
Den Status quo ändern
Für die Google Suche gelten strenge und konservative Anforderungen an die Browserunterstützung. Bisher war es nicht möglich, Funktionen mit eingeschränkter Verfügbarkeit zu nutzen. Bei Übergängen zwischen Dokumenten haben wir festgestellt, dass ein Polyfill nicht praktikabel ist. Der Hauptgrund dafür ist, dass es keine API zum Erstellen von Pixel-Snapshots gab und das Klonen des gesamten Viewports zu erheblichen Leistungsproblemen führte. Daher war es die beste Möglichkeit, die Funktion als progressive Erweiterung zusammen mit dem KI-Modus einzuführen. Da die durch Ansichtsübergänge erstellten Animationen die Funktionalität der Website nicht direkt beeinträchtigen, werden sie für nicht unterstützten Traffic einfach deaktiviert. Das war auch schon der aktuelle Produktionsstatus ohne Übergangsanimationen.
Wir haben diese Strategie zur progressiven Verbesserung zuerst mit unseren internen Nutzern getestet. So konnten wir frühzeitig Feedback erhalten, das überwiegend positiv war. Das Feedback hat auch Fehler aufgezeigt, darunter Leistungsprobleme und unbeabsichtigte Interaktionen mit anderen Funktionen wie überlappenden Stapelkontexten.
Wir haben festgestellt, dass diese Strategie erfolgreich ist, und ich glaube, dass wir sie in Zukunft auch bei anderen neuen Browserfunktionen anwenden werden.
Schwierigkeiten und wie wir sie gelöst haben
Latenz, Blockierung des Renderings und Watchdog-Timer
Insgesamt ist die zusätzliche Latenz, die mit MPA-Ansichtsübergängen einhergeht, für 99% der Anwendungsfälle vernachlässigbar, insbesondere auf moderner Hardware. Bei der Google Suche sind wir jedoch sehr streng, was die Latenz angeht, und wir bemühen uns, Nutzererlebnisse zu schaffen, die auf allen Geräten gut funktionieren. Für uns zählen selbst wenige Millisekunden, daher mussten wir uns genau überlegen, wie wir Übergänge zwischen Dokumenten implementieren können, ohne die Nutzerfreundlichkeit zu beeinträchtigen.
Renderblocking ist eine Technik, die gut mit Ansichtsübergängen zwischen Dokumenten funktioniert. In den Pseudo-Element-Snapshots des eingehenden Dokuments können nur Inhalte angezeigt werden, die bereits gerendert wurden. Wenn Sie also Inhalte aus dem eingehenden Dokument animieren möchten, müssen Sie den Block rendern, bis das zu animierende Zielelement gerendert wurde. Verwenden Sie dazu das Attribut blocking
für ein HTMLLinkElement
. Render-Blocking hat jedoch auch Nachteile, da das Warten auf ein Element, das sich im DOM-Baum des eingehenden Dokuments weiter unten befindet, zu einer erheblichen Latenz führen kann. Wir mussten diesen Kompromiss entsprechend abwägen und das Blockieren nur auf Elemente anwenden, die sehr früh im Seitenlebenszyklus gerendert werden.
<!-- Link tag in the <head> of the incoming document -->
<link blocking="render" href="#target-id" rel="expect">
<!-- Element you want to animate in the <body> of the incoming document -->
<div id="target-id">
some content
</div>
In einigen Fällen reichte es nicht aus, genau anzugeben, für welches Element Sie den Block rendern möchten. Bei bestimmten Geräten oder Verbindungen kann es weiterhin zu zusätzlicher Latenz kommen, auch wenn das Rendern eines Elements in der Nähe des Anfangs des DOM-Baums blockiert wird. Um diese Fälle zu behandeln, haben wir ein Watchdog-Timer-Skript geschrieben, das das HTMLLinkElement
nach einer bestimmten Zeit entfernt, um das Rendern des eingehenden Dokuments zu erzwingen.
Das geht ganz einfach:
function unblockRendering() {
const renderBlockingElements = document.querySelectorAll(
'link[blocking=render]',
);
for (const element of renderBlockingElements) {
element.remove();
}
}
const timeToUnblockRendering = t - performance.now();
if (timeToUnblockRendering > 0) {
setTimeout(unblockRendering, timeToUnblockRendering);
} else {
unblockRendering();
}
Einschränkungen der Abdeckung
Ein weiteres Problem, das wir festgestellt haben, ist, dass die Regel navigation: auto
für Übergänge zwischen Dokumenten auf globaler Ebene innerhalb des Dokuments erfolgt. Es gibt keine integrierte Möglichkeit, die Aktivierung von Übergängen zwischen Dokumenten auf bestimmte Klickziele zu beschränken. Da es sich um eine so große Änderung handelt, konnten wir die Übergänge zwischen Dokumenten nicht für alle Navigationsvorgänge in der Google Suche aktivieren. Wir brauchten eine Möglichkeit, Übergänge zwischen Dokumenten dynamisch zu aktivieren oder zu deaktivieren, je nachdem, mit welcher Funktion der Nutzer interagierte. In unserem Fall haben wir sie nur für Modusänderungen in den und aus dem KI‑Modus aktiviert. Dazu haben wir die Navigation programmatisch aktualisiert, je nachdem, auf welches Ziel geklickt oder getippt wurde.
So können Sie die @view-transition-Regel ein- und ausschalten:
let viewTransitionAtRule: HTMLElement | undefined;
const DISABLED_VIEW_TRANSITION = '@view-transition{navigation:none;}';
const ENABLED_VIEW_TRANSITION = '@view-transition{navigation:auto;}';
function getVtAtRule(): HTMLElement {
if (!viewTransitionAtRule) {
viewTransitionAtRule = document.createElement('style');
document.head.append(viewTransitionAtRule);
}
return viewTransitionAtRule;
}
function disableVt() {
getVtAtRule().textContent = DISABLED_VIEW_TRANSITION;
}
function enableVt() {
getVtAtRule().textContent = ENABLED_VIEW_TRANSITION;
}
Ruckeln und zusammengesetzte Animationen
Einige der automatisch generierten Animationen für die Pseudoelemente für Ansichtsübergänge führten auf älteren Geräten zu Frame-Drops, was die reibungslose Nutzererfahrung beeinträchtigte, die wir Nutzern bieten möchten. Um die Leistung der Animationen zu verbessern, haben wir sie mit Animationstechniken neu geschrieben, die auf dem Compositor ausgeführt werden können. Dazu haben wir die Keyframes untersucht, um die Abmessungen der Pseudo-Elemente des Vorher- und Nachher-Snapshots zu ermitteln, und die Keyframes dann mithilfe von Matrixmathematik entsprechend neu geschrieben. Im folgenden Beispiel wird gezeigt, wie Sie die Animation für jedes Pseudo-Element für den Ansichtsübergang abrufen:
const pseudoElement = `::view-transition-group(${name})`;
const animation = document
.getAnimations()
.find(
(animation) =>
(animation.effect as KeyframeEffect)?.pseudoElement === pseudoElement,
);
Weitere Informationen zum Schreiben von leistungsstarken Keyframes für Ansichtsübergänge finden Sie unter View Transitions Applied: Dealing with the Snapshot Containing Block.
Weitere Hinweise
Eines der wichtigsten Probleme ist, dass das Tagging von Elementen mit der CSS-Eigenschaft view-transition-name
den Stapelkontext beeinflusst (View Transitions Specification: Section 2.1.1). Dies war die Quelle für mehrere Fehler, die eine Änderung der z-index
von Containerelementen erforderten.
Außerdem sollten Sie view-transition-name
-Werte nicht standardmäßig Elementen hinzufügen. Viele Menschen arbeiten an der Google Suche. Damit die view-transition-name
-Werte, die unser Team für Elemente festlegt, nicht mit Werten anderer Teams in Konflikt geraten, haben wir Ansichtsübergangstypen verwendet, um die view-transition-name
-Eigenschaft nur dann bedingt hinzuzufügen, wenn ein bestimmter Ansichtsübergangstyp aktiv ist.
Beispiel-CSS zum Hinzufügen der view-transition-name
von the-element
zu einem Element nur, wenn der Ansichtsübergangstyp von ai-mode
aktiv ist:
html:active-view-transition-type(ai-mode) {
#target {
view-transition-name: the-element;
}
}
Sobald Sie diese CSS-Regeln für alle Ansichtsübergänge eingerichtet haben, können Sie den aktuellen Ansichtsübergangstyp für jede Navigation während der Ereignisse pageswap
und pagereveal
dynamisch ändern.
Beispiel für das Aktualisieren des Ansichtsübergangstyps auf ai-mode
während des pageswap
-Ereignisses.
function updateViewTransitionTypes(
event: ViewTransitionEvent,
types: string[],
): void {
event.viewTransition.types.clear();
for (const type of types) {
event.viewTransition.types.add(type);
}
}
window.addEventListener(
'pageswap',
(e) => {
updateViewTransitionTypes(
e as ViewTransitionEvent,
['ai-mode'],
);
}
);
So vermeiden wir Namenskonflikte und erstellen nicht unnötig Snapshots von Elementen, die beim Wechsel in den KI-Modus und zurück nicht aufgenommen werden müssen.
Schließlich treten Probleme mit dem Stapelkontext nur während des Ansichtsübergangs auf. Um diese Probleme zu beheben, können wir dann die Z-Indizes der generierten Pseudoelemente anvisieren, anstatt die Z-Indizes der ursprünglichen Elemente willkürlich zu ändern, nur um dieses Problem bei der Verwendung von Ansichtsübergängen zu beheben.
::view-transition-group(the-element) {
z-index: 100;
}
Nächste Schritte
Wir planen, Dokumentübergreifende Übergänge für die Google Suche zu verwenden, einschließlich der Integration mit der Navigation API, sobald sie browserübergreifend verfügbar ist. Wir halten euch auf dem Laufenden, was wir als Nächstes entwickeln.