Frame Rates for Web Animation: What Actually Works
A phase-by-phase playbook for choosing, authoring, testing and verifying frame rates for web video, vector and code-driven animation so motion plays smoothly.
Choosing frame rates for web animation looks like a single number on an export dialog, but it is really a chain of decisions that runs from the first storyboard to the moment a visitor's phone draws the last frame. A hero loop exported as video, a Lottie icon, a CSS transition on a menu and a canvas-based product configurator all reach the screen by different routes, and each route treats frame rate differently. Get the chain right and motion feels effortless. Get one link wrong and the same animation stutters, judders or balloons in file size, and nobody on the team can quite explain why it looked fine in the edit suite.
This playbook is for marketers commissioning animated content, in-house designers who ship motion to a website, and developers who have to make that motion play well in the browser. It is organized as a sequence of phases you follow in order: identify the delivery format, choose the rate that fits it, author consistently, build within the device's frame budget, test on real hardware, and verify after the platform has processed the file. Each phase lists its goal, the actions to take, what you should have at the end, and the checks that tell you it worked.
The underlying facts are simple. Most displays refresh 60 times per second. Video for the web is commonly made at 24, 25 or 30 frames per second. Vector animation plays at whatever rate its player targets. And when a device cannot keep up, frames get dropped. Everything below is about working with those facts instead of against them.
The Frame Rate Playbook at a Glance
Before the detail, here is the whole procedure in one view. The phases are sequential for a reason: a frame rate chosen before you know the delivery format is a guess, and a smoothness judgment made before platform encoding is a judgment about a file nobody will ever see.
- Map every delivery format List each place the animation will appear and whether it will arrive as encoded video, vector data (such as Lottie or SVG), CSS or JavaScript-driven motion, or canvas rendering.
- Choose one rate per format Pick 24, 25 or 30 fps for video based on source footage and destination; let vector and code-driven animation follow the display, and set a sensible authoring rate for vector keyframes.
- Author at a single, locked rate Set the project, every composition and every imported asset to the chosen rate, and resolve any mismatched source material before animating.
- Build within the frame budget Keep vector and code-driven animation simple enough that each frame can be produced in the time the display allows.
- Test on mid-range hardware Watch playback on the devices your audience actually uses, not only on the workstation it was built on.
- Verify after platform processing Upload to the real destination, let it re-encode, and judge smoothness from what viewers will receive.
- Diagnose and escalate If motion still stutters on real devices, isolate the cause, fix it, and bring in specialist help when the fix is beyond the team.
If you already know the fundamentals of spacing and timing, you can skip straight to the phases. If not, our guide to frame rate and timing for animation covers how frame counts translate into perceived speed and weight, which is the foundation for everything that follows.
Phase 1: Map Where the Animation Will Actually Play
Goal: know, for every placement, which technology will draw the frames. Frame rate means something different in each case, so this is the phase that prevents most downstream problems.
The four delivery routes
Web animation reaches the screen in roughly four ways, and each has its own relationship with frame rate:
- Encoded video (MP4, WebM, platform-hosted video). The frame rate is baked in at export. The browser shows each stored frame, and the display shows those frames on its own refresh cycle. A 30 fps video on a 60 Hz display shows each frame for two refreshes.
- Vector animation data (Lottie JSON, animated SVG, Rive files). The file stores keyframes and timing, not finished pictures. The player computes each frame at playback time, which is why vector animation plays at the rate the player targets rather than a rate fixed at export.
- CSS and JavaScript-driven motion (CSS transitions and keyframes, the Web Animations API, libraries such as GSAP). There is no authored frame rate at all. The browser advances the animation every time it paints, which on most displays means up to 60 times per second.
- Canvas and WebGL rendering. Your code draws every frame, usually inside a requestAnimationFrame loop, so the frame rate is whatever your code can sustain up to the display's refresh rate.
Actions
Build a simple placement inventory. For each animation, record where it appears (homepage hero, product page, email, social post, in-app onboarding), the route it will take, the likely devices, and whether it autoplays, loops or is triggered by interaction. It is common for one piece of motion to take several routes: a brand sting might ship as a 30 fps MP4 for social, a Lottie file for the website header and a GIF fallback for email. Each of those is a separate delivery with its own frame rate decision.
Also note who controls the final encode. Anything uploaded to a social or video platform will be re-encoded by that platform, and you do not control its settings. Anything self-hosted on your own site is encoded by you and reaches the viewer as you made it. That difference decides how much weight Phase 6 carries for each placement.
Outputs and checks
The output is a table, one row per placement, with the route and destination filled in. The check is simple: could a developer or editor read any row and know whether they are exporting a video, handing over a JSON file or writing code? If a row says only "animation," it is not finished.
- Every placement is listed, including fallbacks for email and older browsers.
- Each placement names one delivery route: video, vector data, CSS/JS or canvas.
- Target devices are noted, with the lowest-powered likely device called out.
- Placements that pass through third-party re-encoding are flagged.
- Autoplay, loop and interaction triggers are recorded for each item.
Phase 2: Choose the Right Frame Rate for Each Format
Goal: one deliberate rate per placement, chosen for the delivery format rather than out of habit. Matching the frame rate to the delivery format is the single most important piece of good practice in this whole subject.
Video: 24, 25 or 30 frames per second
For encoded video, 24, 25 and 30 fps are the common rates, and each has a natural home. 24 fps carries the look audiences associate with film and is widely used for cinematic brand pieces and character animation. 25 fps is standard in regions with a PAL broadcast heritage, including much of Europe. 30 fps (strictly 29.97 in NTSC-derived workflows) is common for web and social video, screen recordings and product demos.
The interaction with display refresh matters more than most teams realize. On a 60 Hz display, 30 fps divides evenly: every video frame is held for exactly two refreshes, so motion cadence is regular. 24 fps does not divide evenly into 60, so frames alternate between being held for three refreshes and two. That uneven cadence, often called judder, is visible on slow horizontal pans and steady scrolling text. 25 fps on a 60 Hz display produces an irregular pattern too. None of this makes 24 fps wrong; film-style content is watched this way every day. It does mean that motion designed for 24 fps should avoid long, slow, even pans of high-contrast detail, which is exactly where uneven cadence shows most.
When 60 fps video is worth it
60 fps video is useful for fast UI screen recordings, gameplay capture and content where fluid motion is the product. For typical marketing animation it roughly doubles the number of frames to encode compared with 30 fps, which raises file size or forces heavier compression for the same size, and it can look unnaturally smooth for character animation. It is a deliberate choice, not an upgrade to reach for by default.
Vector animation: author rate versus playback rate
Vector formats need two decisions. The authoring rate sets the timing grid that keyframes snap to, and it is stored in the file. The playback rate is decided by the player. Many players, including the common Lottie web player, interpolate between keyframes and can render a new frame on every display refresh, so an animation authored at 30 fps can still play at 60 fps on screen. Some players allow subframe rendering to be turned off, locking playback to the authored rate, which is useful when you deliberately want a stepped, hand-drawn feel. Our guide to Lottie and vector animation for the web covers those player settings in detail.
A practical default is to author vector animation at 30 fps (or 60 fps where very quick UI motion needs finer keyframe placement), let the player render at display rate, and reserve locked lower rates for intentional stylistic effects.
CSS, JavaScript and canvas: follow the display
Code-driven animation should not have a hard-coded frame rate at all. The browser's requestAnimationFrame API, documented by MDN, calls your update function before each repaint, generally matching the display's refresh rate. That means your code should calculate positions from elapsed time, not from a frame counter, so an animation takes the same duration on a 60 Hz laptop, a 120 Hz phone and a struggling older tablet that only manages 40 frames per second.
| Delivery route | Where the rate is set | Sensible default | Main risk |
|---|---|---|---|
| Self-hosted video (MP4/WebM) | At export | 30 fps for web and UI; 24 fps for cinematic pieces | Judder on slow pans at 24 fps; file size at 60 fps |
| Platform-hosted video | At export, then platform re-encode | Match the source footage; 24, 25 or 30 fps | Platform processing changing what viewers receive |
| Lottie or animated SVG | Authoring rate in file; playback by player | Author at 30 fps; player renders at display rate | Complex vectors that the device cannot draw in time |
| CSS and Web Animations API | Browser, per repaint | Time-based durations; animate transform and opacity | Animating layout properties that force reflow |
| Canvas or WebGL | Your render loop | requestAnimationFrame with time-based updates | Frame work exceeding the display's frame budget |
Shortcut: if a piece of motion will be delivered both as video and as vector, author it once at 30 fps. That rate exports cleanly to video, divides evenly into 60 Hz displays, and gives vector keyframes a fine enough grid for most brand and UI motion.
Phase 3: Author at One Locked Rate and Keep It That Way
Goal: a project in which every composition, pre-composition, clip and imported asset runs at the same rate. Mixed frame rates in a single piece are one of the most common and most avoidable causes of stutter.
Why mixing rates causes problems
When a 24 fps clip is dropped into a 30 fps timeline, the software has to invent six extra frames every second. It does that either by repeating frames, which produces a small hitch several times a second, or by blending neighboring frames, which produces ghosting on fast motion. The reverse, placing 30 fps material in a 24 fps timeline, discards frames, and motion that was smooth becomes subtly jerky. Nested compositions set to different rates behave the same way, only less visibly, which is why these problems often surface only after export.
Actions
- Set the project rate from the Phase 2 decision before creating any compositions.
- Check the rate of every imported clip, image sequence and pre-built asset. Stock footage, screen recordings and phone video frequently arrive at rates that differ from your project, and phone footage can be variable frame rate.
- Conform or transcode mismatched sources to the project rate before animating over them, rather than letting the timeline interpolate them silently.
- Where a stepped look is wanted, such as animating on twos, achieve it by holding drawings for two frames inside the project rate, not by setting a sub-composition to a lower rate.
- Record the rate in the project name or delivery notes so anyone who opens the file later knows the intended rate.
Stepped timing deserves one more note. Hand-drawn and frame-by-frame work is often animated on twos at 24 fps, giving 12 new drawings per second while the timeline stays at 24. That is a stylistic choice made within a single rate, not a mixed-rate project. If the piece is going to be delivered at 30 fps for the web, decide early whether to keep a 24 fps master and accept pulldown, or animate natively at 30. Our article on frame-by-frame animation covers that trade-off, and animation timing charts show how to plan holds and spacing on paper before committing to a rate.
Outputs and checks
You should have a project in which the frame rate is stated once and inherited everywhere. The check is an audit before rendering: open every composition's settings and every source clip's properties and confirm they match. Most editing and compositing tools can display this information in a column in the project panel, which makes the audit a two-minute job rather than a hunt.
- Project and every composition share one frame rate.
- All source clips are conformed or transcoded to that rate before animation begins.
- Variable frame rate phone or screen recordings have been converted to constant frame rate.
- Stepped timing is achieved with holds, not with lower-rate sub-compositions.
- The chosen rate is written into the project notes and delivery specification.
Phase 4: Build Within the Frame Budget of Real Devices
Goal: animation the device can actually draw on time, every time. High frame rates that devices cannot sustain produce worse results than a lower rate delivered steadily, because dropped frames are uneven and the eye notices irregularity more than it notices a slightly lower rate.
The arithmetic of the frame budget
At 60 frames per second, each frame has about 16.7 milliseconds from start to finish. At 120 Hz, it has about 8.3 milliseconds. At 30 fps, about 33.3 milliseconds. The browser does not give all of that time to your animation: it also has to run scripts, calculate styles, lay out the page, paint and composite. The team behind web.dev's rendering performance guidance recommends keeping your own per-frame work well inside the budget because the browser needs part of each frame for its own housekeeping. When the work overruns, the browser skips that frame and the motion hitches.
Code-driven animation
For CSS and JavaScript animation, the biggest lever is which properties you animate. Changing transform and opacity can usually be handled at the compositing stage without recalculating layout or repainting. Animating width, height, top, left, margins or box shadows can force layout or paint on every frame, which is far more expensive and scales badly with page complexity. Practical rules:
- Move things with transform: translate() rather than changing position properties.
- Scale with transform: scale() rather than resizing, and fade with opacity.
- Do not read layout values (such as an element's height) and write styles in the same loop, which forces the browser to recalculate layout repeatedly.
- Use time-based easing so animations complete in the same duration when frames drop.
- Respect the prefers-reduced-motion setting, which also helps low-powered devices by removing non-essential motion.
Our guide to interface animation goes deeper on durations and easing for UI, which interacts with frame rate: very short transitions of 100 to 200 milliseconds span only 6 to 12 frames at 60 Hz, so a single dropped frame is proportionally more visible than in a two-second hero animation.
Vector animation
Keep vector animation simple enough to play smoothly. The player has to rebuild the picture every frame it renders, so cost rises with the number of layers, shapes and points, and with expensive features such as masks, mattes, blurs and large semi-transparent areas. Concrete habits that help:
- Merge static layers and remove hidden or zero-opacity layers before export.
- Replace masks and track mattes with simpler shapes where the visual difference is small.
- Avoid effects the web player renders poorly or not at all; check the player's supported feature list before designing around an effect.
- Reduce path point counts on traced or imported artwork.
- Pause off-screen animations and do not run many large vector animations at once on one page.
Canvas and WebGL
For canvas work, the render loop must fit inside the budget on the lowest-powered target device, not the fastest. Profile the loop, cache anything that does not change between frames, draw only regions that changed where practical, and cap internal resolution on high-density screens if the fill cost is too high. Our practical guide to HTML5 canvas animation with Adobe Animate covers these settings for Animate-published content specifically, including the document frame rate it writes into the output.
Shortcut: if a vector animation stutters and you are short on time, remove masks and blurs first. They are frequently the most expensive features in a web vector file, and simplifying them often restores smooth playback without touching the timing.
Worked Example: One Hero Animation, Three Deliveries
The following project is illustrative, built to show the arithmetic rather than to describe a real client. A software company wants an eight-second looping animation in its homepage hero, a version for social feeds and a small animated icon that reuses the same brand motif in its onboarding flow.
Deciding the rates
The inventory from Phase 1 produces three placements: a self-hosted background loop on the homepage, platform-hosted video for social, and a vector icon inside the web app. The motion is flat, geometric brand animation with some slow horizontal drift, which rules out 24 fps for the video versions because slow pans are where 24-on-60 judder is most visible. The team authors everything at 30 fps.
| Placement | Route | Rate | Frames for 8 seconds | Per-frame time on screen |
|---|---|---|---|---|
| Homepage hero loop | Self-hosted MP4 and WebM | 30 fps | 240 | 33.3 ms (two refreshes at 60 Hz) |
| Social video | Platform-hosted, re-encoded | 30 fps | 240 | 33.3 ms, subject to platform processing |
| Onboarding icon | Lottie JSON | Authored at 30 fps, rendered at display rate | 240 keyframe slots | 16.7 ms at 60 Hz; 8.3 ms at 120 Hz |
Had the team chosen 60 fps for the hero video, the export would contain 480 frames instead of 240. Modern codecs compress similar consecutive frames efficiently, so the file would not simply double, but for the same visual quality it would be meaningfully larger, and for the same file size it would need heavier compression. For a background loop that sits behind headline text, the extra smoothness would not justify the cost.
What testing revealed
On the design team's workstations, all three versions looked smooth. On a three-year-old mid-range Android phone, the Lottie icon hitched noticeably when it played at the same time as the page's scroll-triggered reveal animations. Profiling showed two large masked shapes and a gaussian blur in the icon were costing most of each frame. Replacing the masks with simple clipped shapes and baking the blur into a flat gradient cut the file's rendering cost enough to hold a steady frame rate on that phone. The authored timing did not change.
The social version looked fine locally but, once uploaded, showed banding in the gradient and slight softness during fast transitions, both results of the platform's re-encode. Raising the bitrate on the upload master and slightly increasing contrast in the gradient reduced both issues. The team would not have seen either problem had they approved the export on their own machines.
The lesson generalizes: the frame rate decision was correct from the start, but the delivered smoothness depended on device capability and platform processing, which only the later phases revealed.
Phase 5: Test on the Mid-Range Devices Your Audience Uses
Goal: evidence that the animation plays smoothly where it will actually be watched. Testing only on fast machines is one of the most common mistakes in web animation, because design and development workstations are often far more powerful than a typical visitor's phone.
Choosing test devices
Use your analytics to see which devices and browsers your visitors use, then pick at least one device from the middle of that range and one from the lower end. A mid-range phone a few years old is usually more representative than the latest flagship. Include at least one high-refresh display if your audience uses them, since code-driven animation will try to run at 90 or 120 Hz there, halving the time available per frame compared with 60 Hz.
What to test and how
- Real page conditions. Test the animation on the actual page with all its scripts, images and other animations loaded, not in isolation. Contention for the main thread is often the real cause of dropped frames.
- Cold and warm loads. Watch the first play on a fresh page load, when the browser is still decoding images and running scripts, as well as later plays.
- Interaction during playback. Scroll, tap and resize while the animation runs. Scroll-linked and interaction-triggered animation is especially sensitive.
- Battery and power saving. Some devices reduce performance or refresh rate in power-saving modes. Test with it on as well as off.
- Browser profiling. Use the browser's performance tools to record a trace while the animation plays. Long frames, layout recalculations inside animation loops and heavy paint regions show up clearly.
Record what you see as specifically as possible: which device, which browser, which moment in the animation, and whether the problem is a steady low frame rate or occasional hitches. Those two symptoms have different causes. A steady low rate points to work that is too heavy every frame. Occasional hitches usually point to something else on the page, such as a script, image decode or garbage collection, interrupting at intervals.
- At least one mid-range and one lower-end device from your audience data have been tested.
- Testing happened on the live page with all other content and scripts loaded.
- Scrolling and interaction during playback have been checked.
- High-refresh displays have been tested if the audience uses them.
- A performance trace has been recorded for any animation that hitched.
- Findings note device, browser, moment and whether the issue is steady or intermittent.
Phase 6: Check Playback After Platform Processing
Goal: judge smoothness from the file viewers actually receive. Judging smoothness before platform encoding is a mistake because video platforms re-encode everything uploaded to them, typically into several versions at different resolutions and bitrates for different connections and devices.
What re-encoding can change
Platform processing can reduce detail during fast motion, introduce banding in smooth gradients, soften fine lines and text, and in some cases alter how frames are delivered. Motion that looked crisp in your export may look smeared at a lower quality tier. Adaptive streaming means different viewers receive different versions of the same upload, so a viewer on a weak mobile connection may see a noticeably rougher file than you do on office broadband.
Actions
- Export a high-quality upload master at the project frame rate, with no frame rate conversion at export.
- Upload to the real destination as a private or unlisted item where the platform allows it.
- Wait until processing has finished; higher-quality versions often appear later than lower-quality ones.
- Watch on a phone and a desktop, at the platform's default quality and at a lower quality setting.
- Compare against your master, focusing on fast motion, gradients, thin lines and on-screen text.
For self-hosted video, the same principle applies to your own encoding pipeline and any content delivery network or media service that transcodes files. If a service generates alternative versions automatically, check those versions, not only your original. Pacing matters here too: content cut quickly for feeds is more exposed to compression artifacts during fast transitions, which our guide to pacing for social video animation discusses alongside how platforms present motion in the feed.
Outputs and checks
The output is a sign-off based on the processed version, with notes on anything that needed correcting at the master stage. The check is whether a reviewer who only ever saw the processed version would approve it. If the answer is no, adjust the master (bitrate, contrast in gradients, thickness of fine lines, speed of fast moves) and upload again.
A Realistic Schedule for Getting Frame Rates Right
Frame rate work does not need its own separate project; it fits inside a normal production schedule if the checks happen at the right moments. The timeline below shows where each phase sits in a typical two-to-three-week production of a modest web animation package. Larger or more complex projects will stretch it, and the durations are ranges to plan around rather than fixed commitments.
- Kickoff (day 1) Build the placement inventory and agree the delivery route and target devices for each placement.
- Pre-production (days 2 to 3) Decide one frame rate per format, write it into the specification, and check the frame rate of every supplied asset.
- Production setup (day 4) Create the project at the locked rate, conform any mismatched sources, and set up export presets.
- Animation (weeks 1 to 2) Animate within the agreed rate, keep vector complexity in check, and export an early rough version for a first device test.
- Mid-point device test (end of week 1 or early week 2) Test rough cuts on mid-range devices to catch performance problems while they are still cheap to fix.
- Final export and upload (week 2 to 3) Export masters, implement code-driven and vector pieces on the real page, and upload videos to their destinations privately.
- Post-processing review (final days) Review everything after platform processing and on real devices, fix issues at the master, and sign off.
The most valuable item on that schedule is the mid-point device test. Discovering that a complex vector file cannot hold its frame rate on a typical phone is a small change in week one and an expensive redesign after sign-off. If you are planning budget and timing for a larger package, our article on scoping animation projects covers how to build these checkpoints into the brief from the start.
Phase 7: Diagnose Stutter and Decide When to Bring In Help
Goal: when motion still does not play smoothly, find the cause quickly and fix it at the right level. Stutter is a symptom with several possible causes, and fixing the wrong one wastes time.
A diagnostic sequence
Work through the likely causes in order of how cheap they are to check:
- Mixed rates. Confirm the source, project and export rates all match. A regular hitch several times per second often means a rate conversion somewhere in the chain.
- Cadence mismatch. If the stutter is a rhythmic unevenness on slow pans in 24 or 25 fps video, it is likely the pulldown pattern on a 60 Hz display. Consider re-exporting at 30 fps or reworking the move to be less exposed.
- Device overload. If the animation runs smoothly on a fast machine and poorly on a mid-range one, the per-frame work is too heavy. Simplify vectors, move code-driven animation to transform and opacity, or reduce canvas work.
- Page contention. If the animation alone plays well but hitches on the full page, other scripts or media are competing for the main thread. Defer non-essential scripts and avoid starting several heavy animations at once.
- Frame-counted code. If an animation runs at different speeds on different displays, the code is advancing per frame instead of per unit of elapsed time. Rewrite it to be time-based.
- Platform processing. If the export is smooth but the published version is not, the issue is in re-encoding. Improve the master or adjust the motion that suffers most.
When specialist help pays off
Bring in help when web animation stutters on real devices and the team cannot isolate or fix the cause. That typically happens when the problem sits between disciplines: a vector file built by a designer, implemented by a developer, running on a page owned by marketing. An experienced web animation team can profile the page, rebuild heavy vector files, move animation onto cheaper properties and set up export presets so the problem does not return. For broader production needs beyond the web, our animation and motion graphics services cover video, character and brand motion in the same consistent pipeline.
It is also worth asking for help earlier, not only when something breaks, if the animation is central to a launch, if it must run on a wide range of hardware, or if nobody on the team has profiled browser rendering before. A short review at pre-production often costs less than a single round of rework after launch.
Common Frame Rate Mistakes and What to Do Instead
Most frame rate problems trace back to a small number of recurring mistakes. Each one maps to a phase in this playbook, which is a useful way to decide where a process needs strengthening.
| Mistake | What goes wrong | What to do instead | Phase |
|---|---|---|---|
| Choosing a high frame rate the device cannot sustain | Frames drop unevenly; motion looks worse than a steady lower rate | Pick the rate for the format and build within the device's frame budget | 2 and 4 |
| Mixing frame rates in one piece | Repeated or blended frames produce regular hitches or ghosting | Lock one rate and conform all sources before animating | 3 |
| Testing only on fast machines | Problems appear only after launch, on visitors' devices | Test on mid-range and lower-end devices from your audience data | 5 |
| Judging smoothness before platform encoding | Approved exports look worse once published | Upload privately and review the processed version | 6 |
| Hard-coding frame counts in code | Animations run at different speeds on different displays | Use time-based updates with requestAnimationFrame | 2 and 4 |
A final point on consistency. Teams that ship a lot of motion benefit from a short house specification: the default rate for each delivery route, the export presets, the list of test devices and the review step after publishing. Written once, it turns this playbook from a set of decisions into a routine, and it gives every new designer, developer and outside partner the same starting point. Keeping the specification alongside archived project files also means that when a piece is revisited months later, its intended frame rate is on record rather than something to be reverse-engineered from an export.
Where this comes from
- MDN Web Docs — requestAnimationFrame
- web.dev — Rendering performance
The figures and practices above come from the sources listed.
Working on something like this?
We take on Motion Graphics & Animation work for teams who want it done once, properly. Tell us what you are building and we will tell you honestly whether we are the right studio for it. Start a project.
Where to go next
Spotted something wrong? Report an error on this page. We correct on the page and say what changed.