Frontend Development 9 min read

Understanding requestAnimationFrame: Usage, Advantages, and Practical Examples

This article explains the requestAnimationFrame API, demonstrates basic and recursive usage with code samples, compares it to setTimeout/setInterval, shows how to cancel frames, and presents real‑world front‑end scenarios such as smooth animations and scroll‑loading optimizations.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding requestAnimationFrame: Usage, Advantages, and Practical Examples

requestAnimationFrame is a browser API that synchronizes JavaScript animation callbacks with the display's refresh cycle, providing front‑end developers a way to create smoother, performance‑friendly animations.

Basic usage involves a single call that executes a callback once:

<script lang="ts" setup>
function init() { console.log('Hello, requestAnimationFrame'); }
requestAnimationFrame(init);
</script>

For continuous animation, the callback must call requestAnimationFrame recursively, allowing the browser to match the callback frequency to the screen's refresh rate.

<script lang="ts" setup>
function init() { console.log('Recursive call'); requestAnimationFrame(init); }
requestAnimationFrame(init);
</script>

The callback receives a single timestamp argument representing the time when the previous frame finished rendering, which can be used to calculate animation progress.

<script setup>
function init(timestamp) { console.log('Timestamp:', timestamp); requestAnimationFrame(init); }
requestAnimationFrame(init);
</script>

To stop an animation, use window.cancelAnimationFrame with the identifier returned by requestAnimationFrame :

<template>
<button @click="stop">Stop</button>
</template>
<script setup>
let reqId;
function loop() { reqId = requestAnimationFrame(loop); }
requestAnimationFrame(loop);
function stop() { cancelAnimationFrame(reqId); }
</script>

Advantages over setTimeout and setInterval include:

Smoother animation because the browser aligns callbacks with VSync signals.

Automatic adaptation to the display's refresh rate (e.g., 60 Hz → ~16.7 ms per frame).

Reduced CPU usage when the page is in a background tab, as the API pauses execution.

Typical use cases demonstrated are:

Simple rotating image

<template>
<div class="earth" :style="imgStyle"></div>
</template>
<script setup>
import { reactive, onMounted, onUnmounted } from 'vue';
const imgStyle = reactive({ transform: 'rotate(0deg)' });
let rafId;
function animate(time) { imgStyle.transform = `rotate(${(time % 10000) / 5}deg)`; rafId = requestAnimationFrame(animate); }
onMounted(() => rafId = requestAnimationFrame(animate));
onUnmounted(() => cancelAnimationFrame(rafId));
</script>
<style scoped>
.earth { width:100px;height:100px;background-image:url('...');border-radius:50%; }
</style>

Scroll‑loading optimization

<template>
<div class="container" ref="scrollRef" @scroll="handleScroll">
<div v-for="item in items" :key="item" class="item">{{ item }}</div>
<div v-if="loading" class="loading">Loading...</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
const items = ref(Array.from({length:50},(_,i)=>`Test ${i+1}`));
const loading = ref(false);
let rafId: number | null = null;
function checkScroll() { /* load more when near bottom */ }
function handleScroll() { if (rafId) cancelAnimationFrame(rafId); rafId = requestAnimationFrame(checkScroll); }
onMounted(() => {/* add listeners if needed */});
onUnmounted(() => { if (rafId) cancelAnimationFrame(rafId); });
</script>

In conclusion, requestAnimationFrame can be employed wherever a page needs smooth, frame‑rate‑aware updates, ranging from simple UI effects to complex game loops and dynamic layout calculations.

frontendperformanceanimationJavaScriptrequestAnimationFrame
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.