Updated
Purpose and timing. Every animation should answer “what changed?” — a menu opened, a card is now selected, this section is about the next thing. Keep interactions under 300ms and page reveals under 600ms. Use an ease-out curve so movement starts quick and lands soft. And animate one thing at a time. The sites that feel bad are the ones where the visitor has to wait for the page to finish performing before they can read it.
GSAP is still the standard for timeline work — sequencing, scroll-triggered scenes, anything with more than two steps. Framer Motion covers most component-level motion in React and Framer projects. Lenis handles smooth scrolling. Plain CSS transitions do the hovers and state changes, and on a lot of these sites that’s 80% of the motion. Rive and Lottie show up for illustrated animation that would be painful to code by hand.
It can, and it’s the most common reason an animated site feels slow. Animate transform and opacity only — those run on the GPU. Avoid animating width, height, top or left, which force layout on every frame. Lazy-load heavy animation libraries below the fold. For SEO, make sure the content exists in the HTML before the animation reveals it. Google reads the page, not the fade-in.
On a real phone, not the desktop emulator. A three-year-old Android will show you every dropped frame a MacBook hides. Check that hover effects have a tap equivalent or aren’t needed. Honour prefers-reduced-motion — a good chunk of visitors have it switched on and expect the site to calm down. Most of the strongest sites here ship a simpler mobile version of their animation rather than the same one scaled down.
It is if motion helps explain the product or the work. Software with state changes, portfolios where the transitions are part of the craft, launches that need one memorable moment. It isn’t if the site is mostly reading — a blog, documentation, a long-form editorial. Those want fast, still pages. When in doubt, build the page without animation first and add motion only where something felt unclear.