Hoe Google een verbonden ervaring creëerde voor zijn nieuwe AI-modus met behulp van weergaveovergangen

Gepubliceerd: 28 augustus 2025

Google Search heeft een van de grootste bereiken ter wereld, waardoor veranderingen in onze gebruikerservaring miljarden gebruikers kunnen beïnvloeden. We droomden al lang van een webervaring die moderner en meer app-achtig aanvoelt. Toen de ontwikkeling van AI Mode begon, wilden we een ervaring creëren waarbij de overgang van standaard zoeken naar AI Mode naadloos en consistent aanvoelt. Toen we hoorden over overgangen tussen documentweergaven, wisten we dat dit perfect bij de functie paste. Deze casestudy beschrijft wat we hebben geleerd bij het toevoegen van de overgangsfunctie tegelijk met de lancering van AI Mode.

Opname van een zoekopdracht met Google Search, waarbij wordt overgeschakeld van de zoekresultaten naar de AI-modus. De overgang wordt gemaakt met behulp van weergaveovergangen.

De overgangen tussen documentweergaven zijn een revolutionaire ontwikkeling voor native browsertools en we zijn benieuwd hoe dit de toekomst van het web zal vormgeven.

Browser Support

  • Chrome: 126.
  • Rand: 126.
  • Firefox: niet ondersteund.
  • Safari: 18.2.

Source

De status quo veranderen

Google Search hanteert strenge en conservatieve eisen voor browserondersteuning. Het gebruik van een functie met beperkte beschikbaarheid was over het algemeen niet toegestaan. Voor overgangen tussen documentweergaven bleek een polyfill niet haalbaar, met als belangrijkste probleem het ontbreken van een API voor pixelsnapshots en het klonen van de volledige viewport, wat aanzienlijke prestatieproblemen opleverde. Daarom was het implementeren van de functie als een progressieve verbetering de beste manier om deze tegelijk met de AI-modus te lanceren. Omdat de animaties die door weergaveovergangen worden gegenereerd geen directe invloed hebben op de functionaliteit van de website, zouden ze voor niet-ondersteund verkeer simpelweg worden uitgeschakeld, wat al de huidige productiestatus was zonder overgangsanimaties.

We hebben deze strategie voor geleidelijke verbetering eerst getest met onze interne gebruikers. Dit leverde ons vroege feedback op, die overweldigend positief was. De ontvangen feedback bracht echter ook bugs aan het licht, waaronder prestatieproblemen en onbedoelde interacties met andere functies, zoals overlappende stapelcontexten.

We hebben vastgesteld dat deze strategie succesvol is en ik denk dat we deze in de toekomst ook zullen toepassen op andere nieuwe browserfuncties.

Moeilijkheden die we tegenkwamen en hoe we die hebben opgelost.

Latentie, renderblokkering en watchdog-timers

Over het algemeen is de extra latentie die gepaard gaat met MPA-weergaveovergangen verwaarloosbaar voor 99% van de gebruikssituaties, vooral op moderne hardware. Google Search stelt echter extreem hoge eisen aan latentie en we streven ernaar om gebruikerservaringen te creëren die goed werken op alle apparaten. Voor ons tellen zelfs een paar extra milliseconden mee, dus moesten we investeren in een goede implementatie van weergaveovergangen tussen documenten, zonder de gebruikerservaring voor wie dan ook te schaden.

Render blocking is een techniek die goed samengaat met overgangen tussen verschillende documentweergaven. De pseudo-element snapshots van het binnenkomende document kunnen alleen inhoud weergeven die al is weergegeven. Om inhoud uit het binnenkomende document te animeren, moet je daarom render blocking toepassen totdat het doelelement dat je wilt animeren, is weergegeven . Gebruik hiervoor het blocking attribuut op een HTMLLinkElement . Render blocking heeft echter ook nadelen, omdat wachten op een element dat zich aan het einde van de DOM-structuur van het binnenkomende document bevindt, een aanzienlijke vertraging kan veroorzaken. We hebben deze afweging zorgvuldig afgewogen en render blocking alleen toegepast op elementen die zeer vroeg in de paginalevenscyclus worden weergegeven.

<!-- 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 sommige gevallen was het niet voldoende om precies aan te geven op welk element de renderblokkering van toepassing was. Bepaalde apparaten of verbindingen ondervonden nog steeds extra latentie, zelfs wanneer de renderblokkering werd toegepast op een element aan het begin van de DOM-structuur. Om deze gevallen op te lossen, hebben we een watchdog-timerscript geschreven dat het HTMLLinkElement na een bepaalde tijd verwijdert om de rendering van het binnenkomende document te deblokkeren.

Een eenvoudige manier om dit te doen is als volgt:

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();
}

Dekkingsbeperkingen

Een ander probleem waar we tegenaan liepen, is dat de overgang tussen documentweergaven via de navigation: auto op globaal niveau binnen het document plaatsvindt. Er is geen ingebouwde manier om het inschakelen van overgangen tussen documentweergaven te beperken tot specifieke klikdoelen. Omdat dit zo'n grote wijziging is, konden we overgangen tussen documentweergaven niet voor 100% van de navigaties in Google Zoeken inschakelen. We hadden een manier nodig om overgangen tussen documentweergaven dynamisch in of uit te schakelen, afhankelijk van de functie waarmee de gebruiker interactie had. In ons geval hebben we ze alleen ingeschakeld voor moduswisselingen van en naar de AI-modus. We deden dit door de navigatieregel programmatisch bij te werken, afhankelijk van welk doel was aangeklikt of getikt.

Een manier om de weergaveovergang bij de regel in of uit te schakelen is als volgt:

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;
}

Schokkerige en samengestelde animaties

Sommige van de automatisch gegenereerde animaties op de pseudo-elementen voor weergaveovergangen veroorzaakten framedrops op oudere apparaten, waardoor de vloeiende en naadloze ervaring die we gebruikers willen bieden, werd aangetast. Om de prestaties van de animaties te verbeteren, hebben we ze herschreven met behulp van animatietechnieken die in de compositor kunnen worden uitgevoerd. We konden dit doen door de keyframes te inspecteren om de afmetingen van de pseudo-elementen voor en na de snapshot te verkrijgen en matrixberekeningen te gebruiken om de keyframes dienovereenkomstig te herschrijven. Het volgende voorbeeld laat zien hoe u de animatie voor elk pseudo-element van de weergaveovergang kunt vastleggen:

const pseudoElement = `::view-transition-group(${name})`;
const animation = document
  .getAnimations()
  .find(
    (animation) =>
      (animation.effect as KeyframeEffect)?.pseudoElement === pseudoElement,
  );

Lees meer over het schrijven van performante keyframes voor weergaveovergangen in Weergaveovergangen toegepast: Omgaan met het Snapshot-bevattende blok .

Andere zaken om op te letten

Een van de meest prominente problemen is dat het taggen van elementen met de CSS-eigenschap ` view-transition-name de stapelcontext beïnvloedt ( Specificatie van weergaveovergangen: Sectie 2.1.1 ). Dit was de bron van meerdere bugs waardoor de z-index van containerelementen moest worden aangepast.

Een ander aandachtspunt is dat het wellicht niet wenselijk is om standaard view-transition-name waarden aan elementen toe te voegen. Er werken veel mensen aan Google Search. Om te voorkomen dat de view-transition-name waarden die ons team aan elementen toewijst, conflicteren met waarden die door andere teams worden gebruikt, maken we gebruik van weergaveovergangstypen om de view-transition-name eigenschap voorwaardelijk toe te voegen, maar alleen wanneer een specifiek weergaveovergangstype actief is.

Voorbeeld van CSS om de view-transition-name van the-element alleen toe te voegen aan een element wanneer het view-transition-type ai-mode actief is:

html:active-view-transition-type(ai-mode) {
  #target {
    view-transition-name: the-element;
  }
}

Zodra je deze CSS-regels hebt ingesteld voor al je weergaveovergangen, kun je het huidige weergaveovergangstype dynamisch wijzigen voor elke navigatie tijdens de pageswap en pagereveal .

Voorbeeld van het bijwerken van het weergaveovergangstype naar ai-mode tijdens de pageswap .

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'],
    );
  }
);

Op deze manier voorkomen we naamconflicten en maken we geen onnodige momentopnamen van elementen die niet hoeven te worden vastgelegd bij het overschakelen naar en van de AI-modus.

Ten slotte zouden eventuele problemen met de stapelcontext zich alleen voordoen tijdens de overgang tussen weergaven. Om deze problemen op te lossen, kunnen we de z-indices van de gegenereerde pseudo-elementen aanpassen, in plaats van willekeurig de z-indices van de originele elementen te wijzigen met als enige doel dit probleem bij het gebruik van weergaveovergangen op te lossen.

::view-transition-group(the-element) {
  z-index: 100;
}

Wat volgt?

We zijn van plan om overgangen tussen documentweergaven te gebruiken voor Google Zoeken, inclusief integratie met de Navigation API zodra deze cross-browser beschikbaar komt. Blijf op de hoogte om te zien wat we hierna gaan ontwikkelen!