Scroll-animaties uit je AI-design: traag of haperend?

Haperende scroll-animaties komen bijna altijd door een zware animatiebibliotheek, door het animeren van eigenschappen als top, height of margin, of door een scroll-listener die bij elk frame rekent. Animeer alleen transform en opacity, start de animatie met IntersectionObserver of met scroll-driven CSS, en zet hem uit voor bezoekers die minder beweging hebben ingesteld.

Damian Madronal Munoz, oprichter

5 min leestijd

Een AI-tool zet graag een entree op elke sectie: blokken die van onderen invliegen, tekst die woord voor woord verschijnt, een achtergrond die langzamer meeschuift dan de rest. Op een snelle laptop in de preview oogt dat soepel. Op een gewone telefoon hapert het, laadt de pagina trager en staat er soms niets tot het script klaar is. Hieronder hoe je meet waar het misgaat, waarom het gebeurt, en een lichte vervanging in CSS en een paar regels JavaScript.

Herken je dit?

  • Scrollen voelt stroperig, vooral op je telefoon.
  • Tekst is even onzichtbaar en verschijnt pas als je ernaartoe scrolt. Met JavaScript uit blijft hij weg.
  • De pagina verspringt als een blok binnenkomt.
  • Lighthouse geeft een slechte score op Total Blocking Time of op Cumulative Layout Shift.
  • In package.json staat een animatiebibliotheek, en een pakket voor smooth scrolling dat het scrollen van de browser overneemt.

De animatie werkt tegen de browser in

Een browser kan transform en opacity animeren zonder de pagina opnieuw op te bouwen. Animeer je top, height, width of margin, dan moet hij bij elk frame de layout opnieuw uitrekenen, en op een gewone telefoon lukt dat vaak niet vloeiend. Verandert de hoogte van een blok tijdens de animatie, dan schuift alles eronder mee. Dat is de verspringing die Lighthouse meet.

Veel gegenereerde code luistert naar het scroll-event en meet bij elke beweging de positie van elk blok. Dat werk gebeurt op dezelfde draad die ook je klikken en je tekst verwerkt. Een pakket voor smooth scrolling maakt het erger: dat vervangt het scrollen van de browser door een eigen versie in JavaScript.

En de meeste reveal-animaties beginnen met opacity: 0. Wordt het script laat geladen, of loopt het vast, dan blijft de inhoud onzichtbaar. Een bezoeker met een trage verbinding ziet een lege pagina.

Zo maak je het licht

1. Meet eerst waar het hapert

Open de pagina in Chrome en open DevTools. Kies in het paneel Performance bij CPU een vertraging van vier keer, start een opname en scrol de pagina door. Taken met een rood hoekje duren te lang; dat is werk dat het scrollen ophoudt. In het paneel Rendering zet je Layout Shift Regions aan; elk vlak dat blauw oplicht, verspringt.

2. Zichtbaar als standaard, beweging als extra

Een blok is zichtbaar tot een script het verbergt, niet andersom. Zet bovenin de <head> een klasse op de pagina zodra JavaScript draait, en verberg blokken alleen als die klasse er is.

<script>document.documentElement.classList.add('js')</script>

.reveal {
  transition: opacity 500ms cubic-bezier(.2, .7, .2, 1),
              transform 500ms cubic-bezier(.2, .7, .2, 1);
}

.js .reveal:not(.is-zichtbaar) {
  opacity: 0;
  transform: translateY(24px);
}
Zonder JavaScript staat alles er gewoon; alleen met script begint een blok onzichtbaar.

Geef de klasse reveal niet aan iets boven de vouw. De kop en de eerste alinea staan er meteen. Zo houden we het op naltex.nl ook: niets boven de vouw wacht op een animatie, en zonder JavaScript is niets verborgen.

3. IntersectionObserver in plaats van een scroll-listener

Met IntersectionObserver vertelt de browser zelf wanneer een blok in beeld komt. Je script doet dan niets tot het moment dat het nodig is, en niet bij elk frame.

const blokken = document.querySelectorAll('.reveal');

const observer = new IntersectionObserver((entries) => {
  for (const entry of entries) {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-zichtbaar');
      observer.unobserve(entry.target);
    }
  }
}, { rootMargin: '0px 0px -10% 0px' });

blokken.forEach((blok) => observer.observe(blok));
Zet de klasse is-zichtbaar als een blok in beeld komt, en kijkt daarna niet meer naar dat blok.

Het blok animeert één keer. Scrol je terug, dan staat het er gewoon.

4. Of zonder JavaScript: scroll-driven CSS

Nieuwere browsers kunnen een animatie koppelen aan de positie van een element in beeld, helemaal in CSS. Niet elke browser kan het al. Met @supports krijgt een browser die het niet kent gewoon het blok zonder animatie. Kies deze aanpak of die van stap 2 en 3, niet allebei op hetzelfde element.

@supports (animation-timeline: view()) {
  .reveal-css {
    animation: binnenkomen linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 100%;
  }
}

@keyframes binnenkomen {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: none; }
}
Het blok komt binnen terwijl het in beeld schuift; browsers zonder ondersteuning slaan de animatie over.

5. Minder beweging voor wie dat heeft ingesteld

Op een Mac, iPhone of Android-telefoon kun je instellen dat je minder beweging wilt. Mensen die daar last van hebben, zetten dat aan. Je site hoort zich eraan te houden, in CSS en in JavaScript.

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .js .reveal:not(.is-zichtbaar),
  .reveal-css {
    opacity: 1;
    transform: none;
    transition: none;
    animation: none;
  }
}

// en in het script, vóór de observer
if (matchMedia('(prefers-reduced-motion: reduce)').matches) {
  blokken.forEach((blok) => blok.classList.add('is-zichtbaar'));
}
Bij minder beweging staat alles direct op zijn plek, zonder overgang.

Een media query in CSS stopt geen animatie die in JavaScript draait. Gebruik je een bibliotheek, controleer dan of die zelf naar deze instelling kijkt.

6. Op een telefoon: minder, en korter

Laat het scrollen aan de browser en verwijder het pakket voor smooth scrolling. Houd verplaatsingen klein, rond de 16 tot 24 pixels, en kies één moment op de pagina dat beweegt in plaats van elke sectie. Wil je dat je AI-tool het zo ombouwt, geef dan een opdracht die precies zegt wat er moet blijven.

Vervang de scroll-animaties door IntersectionObserver.
Animeer alleen transform en opacity, maximaal 24px verplaatsing, één keer per blok.
Niets boven de vouw krijgt een animatie.
Zonder JavaScript en bij prefers-reduced-motion is alles direct zichtbaar.
Verwijder de animatiebibliotheek en het pakket voor smooth scrolling uit package.json.
Een opdracht om de animaties van een gegenereerde site licht te maken.

Veelgemaakte fouten

  1. Inhoud verbergen tot het script draait. Laadt het script laat of niet, dan blijft de pagina leeg.
  2. Elke sectie dezelfde entree. Na de derde keer kijkt niemand meer, en de pagina voelt trager dan hij is.
  3. Een achtergrond die bij elk scrollframe opnieuw wordt berekend. Een parallax-effect in JavaScript is precies het werk dat een telefoon niet bijhoudt.
  4. Minder beweging alleen in CSS regelen. Animaties uit een script draaien dan gewoon door.

Wanneer je hulp nodig hebt

Is de site na het opruimen van de animaties nog traag, dan zit het vaak in afbeeldingen, lettertypes of scripts van derden: een trage website sneller maken loopt die langs. Beweging hoort ook bij toegankelijkheid; de rest daarvan staat in is je AI-design toegankelijk.

Wil je dat iemand de animaties van je bestaande site ombouwt en meet wat het oplevert, dan doen we dat bij AI-design laten verbeteren. Moet je ontwerp nog een website worden, dan bouwen we de beweging bij AI-design omzetten naar een echte website meteen licht. Alle gidsen staan in het overzicht van AI-design.

Veelgestelde vragen⁠

Zijn scroll-animaties slecht voor mijn vindbaarheid?

Niet zolang de tekst in de HTML staat en zonder JavaScript zichtbaar is. Ze kosten je wel iets als ze het grootste element op de pagina laten wachten of de pagina laten verspringen. Die twee tellen mee in de Core Web Vitals van Google.

Moet ik mijn animatiebibliotheek weggooien?

Niet altijd. Voor één complexe, getimede animatie op één plek kan een bibliotheek de moeite waard zijn. Voor blokken die bij het scrollen invaden heb je hem niet nodig; dat doet de browser zelf, en sneller.

Hoe lang mag een animatie duren?

Kort. Een blok dat in ongeveer een halve seconde binnenkomt, met een kleine verplaatsing, voelt rustig. Duurt het langer, dan wacht de lezer op je animatie in plaats van op je tekst.

Hoe test ik minder beweging zonder mijn eigen instellingen te veranderen?

Open in Chrome de DevTools, kies het paneel Rendering en zet prefers-reduced-motion op reduce. De pagina gedraagt zich dan zoals bij iemand die beweging heeft uitgezet.

Verder lezen⁠

Een ontwerp uit Claude Design, Stitch of Figma Make dat een echte website moet worden, en dat er niet als AI uit mag zien.

Wij maken je site rustig en snel⁠

De kennismaking is gratis. We reageren binnen één werkdag.