WebTech1223411 logo WebTech1223411Web tech, read closely
Games

Discover the Web Code Behind Smooth Online Game Animations

Smoothness is the first thing players notice in a browser game and the last thing they can describe. A character that runs at a steady 60 frames per second just feels right.

Abstract illustration for Discover the Web Code Behind Smooth Online Game Animations

Smoothness is the first thing players notice in a browser game and the last thing they can describe. A character that runs at a steady 60 frames per second just feels right. The same character dropping to 45 frames now and then feels cheap, even if nobody can say exactly why. Behind that feeling is a small amount of code doing the same job over and over, roughly every 16.7 milliseconds, and it has to finish on time every single time.

I came to games from interface design, where a dropped frame in a menu is a minor irritation. In an online game it is a missed jump. Here is what the web code behind smooth game animation actually does, and why some approaches work so much better than others.

The frame budget

Most screens refresh 60 times per second, which leaves about 16.7 milliseconds per frame. High refresh displays at 120 Hz halve that budget to roughly 8.3 milliseconds. Inside that window the browser must run your game logic, apply style changes, calculate layout if anything moved, paint, and composite the result.

The browser itself needs a few milliseconds of that time. In practice a game has around 10 milliseconds for its own work at 60 Hz. Go over and the frame is late, the display shows the previous one again, and the player sees a stutter. Smooth animation is therefore not about doing things quickly on average. It is about never missing the deadline.

requestAnimationFrame is the heartbeat

Old browser games used setInterval or setTimeout to drive their loops. Those timers are not tied to the screen refresh, so updates drift in and out of step with the display and produce uneven motion. They also keep running in background tabs, wasting battery.

requestAnimationFrame fixes both. You hand the browser a callback and it calls it just before the next repaint, at whatever rate the display runs. It passes a high-resolution timestamp, so you can measure exactly how much time passed since the last frame. In background tabs it pauses automatically.

A typical game loop calls requestAnimationFrame once per frame, reads the input, updates the world, draws, and schedules itself again. Everything else is about keeping that loop inside its budget.

Time-based movement, not frame-based

A classic beginner mistake is moving a character a fixed number of pixels per frame. On a 60 Hz monitor it looks fine. On a 120 Hz monitor the character runs twice as fast, and on a struggling laptop it slows down whenever frames drop.

The fix is to multiply movement by elapsed time. If a character should travel 300 pixels per second and 8 milliseconds passed, it moves 2.4 pixels. Many games go further and run physics on a fixed timestep, say 60 updates per second, regardless of the display rate, then interpolate between physics states when drawing. This keeps physics stable and deterministic, which also matters for online play, where clients need to agree on what happened.

Canvas and WebGL games: drawing every frame

Most action games draw into a <canvas>, either with the 2D context or with WebGL. Each frame they clear the canvas and redraw the scene. Animation then comes from changing what is drawn, usually by stepping through frames of a sprite sheet: one image containing every frame of a run cycle, with the code drawing a different slice of it each time.

Sprite sheets and texture atlases matter for speed. Drawing many small pieces from one big image lets the GPU batch the work into far fewer draw calls than loading dozens of separate files. The same trick powers the spinning reels in many casual titles, which we break down in how online slot games render graphics in the browser.

DOM and CSS animation for interfaces

Not everything belongs on a canvas. Menus, inventory screens, scoreboards and notifications are often built with regular HTML and CSS, because text is sharper, layouts adapt to screen size, and accessibility comes for free.

For these, the rule is simple: animate transform and opacity. Those two properties can usually be handled by the compositor on the GPU without repeating layout or paint. Animating top, left, width or height forces the browser back through layout on every frame, and with a busy game running in the background that is often what pushes a frame over budget. The rendering pipeline behind this is described in what happens between typing a URL and seeing a page.

The "always use a JavaScript animation library" habit

It is common advice to reach for an animation library for every moving element. Libraries are useful for complex sequenced motion, but I think the advice is often wrong for game interfaces.

A CSS transition or a Web Animations API call on transform runs on the compositor thread. If the main thread is busy with game logic, the CSS animation can still keep moving smoothly. Many JavaScript animation libraries update styles from the main thread on every frame, so when the game gets busy, the menu stutters too. For simple fades, slides and pops in an online game interface, the native options are lighter and often smoother. Save the library for choreography that genuinely needs it.

Avoiding the hidden frame killers

Even well-written loops can stutter. The usual causes are not the drawing code itself:

  • Garbage collection pauses. Creating new objects every frame, like vectors or arrays, eventually triggers a collection that can take several milliseconds. Reusing objects from a pool avoids it.
  • Layout thrashing. Reading a layout value such as offsetWidth right after changing styles forces the browser to calculate layout immediately, sometimes several times per frame.
  • Decoding images mid-game. Loading a large image on demand can block a frame while it decodes. Preload and decode assets before they are needed.
  • Too many draw calls. Hundreds of separate draws per frame overwhelm the GPU pipeline. Batch them with atlases.

Finding which of these is to blame is a job for the Performance panel. Our walkthrough on how developer tools help debug online game performance shows how to read a recording and spot exactly which frame went over budget.

Respecting players who want less motion

One last point that is easy to forget: some players get headaches or nausea from heavy motion. The prefers-reduced-motion media query tells you when someone has asked their system for less animation. Good games respond by toning down screen shake, parallax and flashy transitions while keeping the core gameplay intact.

Smooth animation in an online game is not magic. It is a timing loop, time-based movement, the right drawing method for each layer, and a lot of care about what happens inside each 16 milliseconds. Find more of our coverage in the Games section.

LV
Lorenzo Vidal

Lorenzo started as a visual designer and moved into CSS after watching too many of his layouts fall apart on phones. He writes about front-end craft, interfaces and accessibility, and still tests everything with the keyboard first.

More posts by Lorenzo

More in Games