アニメーションを滑らかに! `requestAnimationFrame` でブラウザの「描画」と仲良くなろう!
Webサイトでキラキラ動くアニメーションや、スルスルっと表示が変わるUI、見ていて楽しいですよね! でも、その「動き」をうまく作るのって、意外と奥が深いんです。もしかしたら、「なんでこのアニメーション、カクカクするんだろう?」とか、「気づいたらブラウザが重たくなっちゃった…」なんて経験、あるかもしれません。
大丈夫、大丈夫! 今日はそんな悩みを解決してくれる、魔法のようなAPI、「`requestAnimationFrame`」(リクエスト・アニメーション・フレーム)について、とことん優しく、そして分かりやすく解説していきますね。Webブラウザの「描画」の仕組みと仲良くなれば、きっとあなたのWeb制作はもっと楽しく、もっとパワフルになりますよ!
ブラウザのお仕事、覗いてみよう! ~描画の裏側~
まず、私たちのWebブラウザが、どうやって画面に絵を描いているのか、その裏側をちょっとだけ覗いてみましょう。これを理解すると、`requestAnimationFrame` がどれだけ賢いAPIなのか、きっと納得してもらえるはずです。
ブラウザは、私たちが書いたHTML、CSS、JavaScriptを元に、画面に表示するための「絵」を描き直す作業を、常に繰り返し行っています。この一連の作業を「ブラウザの描画サイクル」と呼ぶんですが、これは例えるなら、お料理のプロセスに似ています。
🍳 お料理に例えてみよう! ブラウザの描画サイクル
1. 材料の準備(HTML/CSSの解析・DOMツリー構築): まず、レシピ(HTML)を読んで、どんな料理を作るか決めます。そして、材料(CSS)をどう使うか、どこに配置するかを考えます。
2. 下ごしらえ(スタイル計算・レイアウト計算): 材料をどう切るか(スタイル)、どこに置くか(レイアウト)を決めます。ここが、ブラウザでいう「リフロー」とか「レイアウト」と呼ばれる部分。要素のサイズや位置が決まる、すごく大事な工程です。
3. 盛り付け(ペイント): 下ごしらえが終わった材料を、お皿に綺麗に盛り付けます。これが「リペイント」や「ペイント」と呼ばれる部分。文字の色を変えたり、背景色を塗ったりするイメージです。
4. 最終調整(コンポジット合成): 盛り付けた料理を、さらに装飾したり、他の料理と合わせて完成させます。ブラウザでは、複数のレイヤー(絵の層)を重ね合わせて、最終的な画面を作り上げます。これを「コンポジット合成」と呼びます。
この一連のお料理プロセス、つまり描画サイクルは、だいたい1秒間に60回くらい、ものすごいスピードで繰り返されています。(※厳密にはディスプレイのリフレッシュレートに依存します)
🤔 なんで、この「お料理」のタイミングが大事なの?
もし、私たちが料理の途中で、いきなり「あ、この材料、もっと小さくしよう!」とか「こっちに移動させよう!」と、頻繁に調理プロセスを中断させてしまったらどうなるでしょう?
- 無駄な作業が増えちゃう!: 下ごしらえが終わったのに、また最初からやり直し…なんてことになったら、時間がかかって大変ですよね。
- 仕上がりがガタガタに…: 料理が落ち着いていないのに、無理やり盛り付けたりすると、見た目も悪くなっちゃいます。
Webブラウザも同じ。描画サイクルが終わっていないのに、JavaScriptで要素のサイズを変えたり、位置を動かしたりすると、ブラウザは「えっ、もう一回、下ごしらえからやり直さなきゃ!」って、無駄なリフローやリペイントをたくさん発生させてしまうんです。これが、カクカクしたアニメーションや、ブラウザの重さの原因になることがあります。
`requestAnimationFrame` の登場! ~ブラウザの「描画」と仲良くなろう~
そこで登場するのが、今日の主役、「`requestAnimationFrame`」です!
このAPIは、ブラウザの描画サイクルが「よし、次から次へと画面を描き直すぞ!」と、準備を始めたタイミングで、「あなたの処理、このタイミングで実行しますね!」と、優しく教えてくれるんです。
例えるなら、お料理のシェフが「さあ、次の皿の盛り付けを始めるよ!」って声をかけてくれるタイミングで、あなたが「このソースをかけます!」とか「この飾りを添えます!」って、一番効率よく、そして綺麗に仕上がるように作業できる、そんなイメージです。
✨ `requestAnimationFrame` のここがすごい!
- ブラウザの描画サイクルに合わせる: ブラウザが「描画するぞ!」と決めたタイミングで処理を実行するので、無駄なリフローやリペイントが減ります。
- パフォーマンス向上: 無駄な処理が減ることで、ブラウザへの負荷が軽くなり、アニメーションが滑らかになります。
- バッテリー消費も抑える: ブラウザが不要な描画をしないようになるので、ノートパソコンやスマートフォンのバッテリー消費を抑える効果も期待できます。
- バックグラウンドでは実行しない: タブを切り替えたり、ウィンドウを閉じたりして、画面に表示されていないときは、自動的に処理を停止してくれるので、さらに効率的です。
実際の使い方を見てみよう! ~簡単なアニメーションを動かしてみる~
では、実際に`requestAnimationFrame`を使って、簡単なアニメーションを動かしてみましょう。ここでは、四角いボックスが右に移動するアニメーションを作ってみます。
まずは、HTMLとCSSの準備です。
このHTMLをブラウザで開くと、左上に水色の四角いボックスが表示されているはずです。
次に、JavaScriptで`requestAnimationFrame`を使ったアニメーションを書いていきましょう。
// DOM要素を取得
const box = document.querySelector(‘.box’);
// アニメーションの開始位置
let position = 50; // CSSのleftの値と同じ
// 移動する速さ (ピクセル/フレーム)
const speed = 2;
// アニメーションを続けるための関数
function animate() {
// 位置を更新
position += speed;
// ボックスのleftスタイルを更新
box.style.left = position + ‘px’;
// 画面の描画タイミングで、もう一度 animate 関数を呼び出す
// これでアニメーションがループします!
requestAnimationFrame(animate);
}
// アニメーションを開始!
animate();
さあ、このJavaScriptコードをHTMLの`

コメント