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

Gepubliceerd: 28 aug. 2025

Google Zoeken heeft een van de grootste reikwijdtes ter wereld, waardoor veranderingen in onze gebruikerservaring impact kunnen hebben op miljarden gebruikers. We dromen al lang van een webervaring die moderner en app-achtiger aanvoelt. Toen we begonnen met de ontwikkeling van AI Mode , wilden we een ervaring voor onze gebruikers creëren waarbij de overgang van standaard zoeken naar AI Mode naadloos en consistent aanvoelde. Toen we hoorden over overgangen tussen documentweergaven, wisten we dat dit een perfecte aanvulling was op deze functie. Deze casestudy laat zien wat we hebben geleerd door de overgangsfunctie toe te voegen aan de lancering van AI Mode.

Opname van een zoekopdracht op Google Zoeken, waarbij van de zoekresultaten wordt overgeschakeld naar de AI-modus. De overgang vindt plaats via weergaveovergangen.

Overgangen tussen documentweergaven veranderen het spel als het gaat om native browsertools en we zijn benieuwd hoe het het web in de toekomst zal vormgeven.

Browser Support

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

Source

De status quo veranderen

Google Zoeken stelt strenge en conservatieve eisen aan browserondersteuning. Over het algemeen was het gebruik van een functie met beperkte beschikbaarheid verboden terrein. Voor overgangen tussen documenten vonden we een polyfill niet houdbaar, met als belangrijkste struikelblok de afwezigheid van een API voor pixelsnapshots en het klonen van de volledige viewport leidde tot grote prestatieproblemen. Daarom was het gebruik van de functie als een progressieve verbetering de beste manier om deze naast de AI-modus te lanceren. Omdat de animaties die door overgangen in de weergave worden gemaakt geen directe invloed hebben op de functionaliteit van de website, zouden ze voor niet-ondersteund verkeer eenvoudigweg worden uitgeschakeld, wat al de huidige productiestatus was zonder overgangsanimaties.

We hebben deze progressieve verbeteringsstrategie eerst getest met onze interne gebruikers. Dit leverde ons al snel overweldigend positieve feedback op. De ontvangen feedback bracht ook bugs aan het licht, waaronder prestatieproblemen en onbedoelde interacties met andere functies, zoals overlappende stacking-contexten.

Wij vinden deze strategie succesvol en ik denk dat we deze in de toekomst ook bij andere nieuwe browserfuncties zullen toepassen.

Moeilijkheden die we tegenkwamen en het oplossen ervan

Latentie, renderblokkering en watchdog-timers

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

Render blocking is een techniek die goed samengaat met cross-document view transitions. De pseudo-element snapshots van het inkomende document kunnen alleen content weergeven die al is gerenderd. Om content uit het inkomende document te animeren, moet u daarom block renderen totdat het gewenste element is gerenderd . Gebruik hiervoor het blocking attribuut op een HTMLLinkElement . Render blocking heeft nadelen, omdat wachten op een element dat zich aan het einde van de DOM-tree van het inkomende document bevindt, een aanzienlijke latency-impact kan hebben. We moesten deze afweging zorgvuldig afwegen en block alleen renderen op elementen die extreem vroeg in de levenscyclus van de pagina worden gerenderd.

<!-- 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 te bepalen op welk element je een blokkering renderde. Bepaalde apparaten of verbindingen vertoonden nog steeds extra latentie, zelfs bij het renderen van een blokkering op een element aan het begin van de DOM-tree. Om deze gevallen aan te pakken, hebben we een watchdog-timerscript geschreven om het HTMLLinkElement na een bepaalde tijd te verwijderen, zodat de blokkering van het inkomende document wordt opgeheven.

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 dat we tegenkwamen, is dat de at-rule navigation: auto plaatsvindt op globaal niveau binnen het document. Er is geen ingebouwde manier om de inschakeling van overgangen tussen documentweergaven te beperken tot specifieke klikdoelen. Omdat dit zo'n grote wijziging is, konden we niet voor 100% van de navigaties in Google Zoeken overgangen tussen documentweergaven 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 moduswijzigingen van en naar de AI-modus. We hebben dit gedaan door de at-rule navigatie programmatisch bij te werken, afhankelijk van het doel waarop werd geklikt of getikt.

U kunt de at-rule-weergaveovergang als volgt in- of uitschakelen:

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

Jank en samengestelde animaties

Sommige van de automatisch gegenereerde animaties op de pseudo-elementen van de weergaveovergang veroorzaakten frame drops op oudere apparaten, wat de overzichtelijke, naadloze ervaring die we gebruikers willen bieden, verstoorde. Om de prestaties van de animaties te verbeteren, hebben we ze herschreven met animatietechnieken die op de compositor kunnen draaien. We konden dit doen door de keyframes te inspecteren om de afmetingen van de pseudo-elementen van de voor- en na-snapshot te bepalen en matrixberekening 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 Toegepaste weergaveovergangen: omgaan met het blok dat momentopnamen bevat .

Andere dingen waar u op moet letten

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

Houd er ook rekening mee dat u mogelijk geen waarden voor view-transition-name standaard aan elementen wilt toevoegen. Er werken veel mensen aan Google Zoeken. Om te voorkomen dat de waarden voor view-transition-name ons team voor elementen instelt, conflicteren met waarden die mensen van andere teams mogelijk gebruiken, hebben we gebruikgemaakt van view transition types om de eigenschap view-transition-name alleen voorwaardelijk toe te voegen wanneer een specifiek type view transition actief is.

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

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

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

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

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 niet onnodig momentopnamen van elementen die niet gemaakt hoeven te worden bij de overgang van en naar de AI-modus.

Ten slotte zouden eventuele problemen met de stapelcontext alleen optreden tijdens de weergaveovergang. Om deze problemen op te lossen, kunnen we ons richten op de z-indices van de gegenereerde pseudo-elementen, in plaats van willekeurig de z-indices van de oorspronkelijke elementen te wijzigen, enkel en alleen om dit probleem op te lossen bij het gebruik van weergaveovergangen.

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

Wat volgt er?

We zijn van plan om cross-document weergave-overgangen te gebruiken voor Google Zoeken, inclusief integratie met de Navigatie API zodra deze browseronafhankelijk beschikbaar is. Blijf op de hoogte van wat we nog meer gaan bouwen!