1. requestAnimationFrameとは?
JavaScriptで「なめらかなアニメーション」を作るときに使うのが
requestAnimationFrame(rAF) です。
例えば:
- 要素を横にスライドさせる
- 数字をカウントアップさせる
- ルーレットを回転させる
こうした動きはすべて、
画面の更新タイミングに合わせて処理を繰り返す仕組みで作られています。
その仕組みを提供しているのが requestAnimationFrame です。
2. なぜアニメーションには「更新ループ」が必要なのか?
アニメーションは「1回の処理」で動いているわけではありません。
位置を更新 → 画面を描画 → 位置を更新 → 画面を描画という処理を何度も繰り返すことで、
私たちは「動いている」と感じます。
この繰り返し処理のことを ループ と呼びます。
requestAnimationFrameは、
このループを自然に作るためのAPIです。
3. 基本の使い方
最小構成はこれだけです。
let x = 0;
const box = document.getElementById("box");
function animate() {
x += 5;
box.style.transform = `translateX(${x}px)`;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);ポイント
- animate の中で自分自身を呼び出している
- これによりループが完成する
この構造が、アニメーションの基本形です。
4. ブラウザはどのタイミングで動いている?
ブラウザは通常、
1秒間に約60回画面を更新しています。
これを「60fps(frames per second)」と呼びます。
私たちが「なめらか」と感じる動きは、
この更新タイミングにうまく合わせることで実現しています。
requestAnimationFrameは、
「今から画面を描きますよ」という直前のタイミング
で関数を実行します。
つまり、ブラウザの描画と同期して動くのです。
5. setIntervalとの違い
昔はアニメーションをこう書いていました。
setInterval(() => {
x += 5;
box.style.transform = `translateX(${x}px)`;
}, 16);一見問題なさそうですが、違いがあります。
| setInterval | requestAnimationFrame |
|---|---|
| 時間で実行 | 描画タイミングで実行 |
| 描画とズレる可能性あり | 描画と同期する |
| タブ非表示でも動く | 非表示時は自動停止 |
| カクつきやすい | 滑らか |
フレームレートや60fpsの仕組みについては、別記事で詳しく解説しています。
なぜズレるの?
setIntervalは「16msごとに実行する」だけです。
しかしブラウザの描画タイミングとは必ずしも一致しません。
その結果、
- 更新が間に合わない
- 無駄な再描画が起きる
- カクつきが発生する
といった問題が出ます。
requestAnimationFrameはこの問題を避けられます。
6. ループ構造の理解
この1行が重要です。
requestAnimationFrame(animate);animateの中で再び animate を呼び出すことで、
描画 → 呼び出し → 描画 → 呼び出しという循環が完成します。
この構造は、後に扱う
- ゲームループ設計
- Update / Render 分離
- 時間制御
の原型になります。
ここではまず、
「描画に合わせて繰り返す」感覚を掴むことが目的です。
7. よくある疑問
Q. setIntervalはもう使わない?
いいえ。
- 一定時間ごとのログ出力
- 通信ポーリング
- 単純な繰り返し処理
などには今でも使われます。
ただし「描画を伴うアニメーション」では
requestAnimationFrameが基本になります。
8. まとめ
- requestAnimationFrameは描画タイミングと同期するAPI
- アニメーションはループ構造で作られる
- setIntervalより自然で効率的
- 現代のアニメーション実装の基本
まずは「動かす」ことが第一歩です。
9. まだ1つ解決していない問題
ここまでで rAF の構造は理解できました。
ですが、まだ1つ問題が残っています。
私たちは今、
x += 2;と書いています。
これは「フレーム依存」です。
もしフレーム間隔が毎回同じでなかったら?
一度、確かめてみましょう。
10. 実験:rAFは本当に“毎回同じ間隔”で動いている?
🎯 この実験の目的
- requestAnimationFrame は「60fps固定」ではない
- フレーム間隔(dt)は毎回微妙に違う
- フレーム依存の書き方には問題がある
これを体感します。
観察ポイント
① dtは毎回同じではない
16.6ms前後ですが、完全な固定ではありません。
② 他の作業をすると数値が大きくなる
- 別タブを開く
- ウィンドウを動かす
- CPU負荷をかける
→ dt が跳ねます。
③ なのに、移動量は毎回「2px固定」
ここが重要です。
x += 2;は、時間ではなく
「フレーム回数」依存
で動いています。
ここで生まれる疑問
もし、
- 高リフレッシュレートのモニター
- CPUが遅い環境
- 負荷がかかった状態
だったら?
アニメーション速度は同じでしょうか?
答えは「同じではありません」。
この問題を解決する考え方が、
deltaTime(経過時間ベースで動かす設計)
です。
次の記事では、
- フレーム依存からの脱却
- 環境に左右されない速度制御
を解説します。
🔎 このラボの全体像はこちら
→ UI Architecture Roadmap

コメントを残す