ทำ Animation ใช้ setInterval หรือ requestAnimationFrame ดีกว่ากัน

Animation on HTML5 Canvas with setInterval VS requestAnimationFrame

GatoMaster
2 min readDec 12, 2018

ในการทำ Animation บน HTML5 Canvas ใน JavaScript จะมีการเรียกอัปเดต Animation ซึ่งเราจะใช้ method ในการเรียกอัปเดตด้วยกันสองตัวคือ requestAnimationFrame กับ setInterval ถ้าหากเราไม่รู้ว่าจะใช้ตัวไหนมาลองดูความแตกต่างของสองตัวนี้กัน

requestAnimationFrame จะรีเฟรช fps ตาม web browsers

[Syntax]
window.requestAnimationFrame(callback);

setInterval ระบุเวลาที่มีหน่วยเป็น milliseconds ในการเรียกใช้งานฟังก์ชั่นซ้ำๆ

[Syntax]
setInterval(function, milliseconds, param1, param2, …)

จากการทำงานที่แตกต่างกันระหว่างสองตัวนี้ทำให้มีผลกระทบกับการทำงาน Animation เนื่องจาก setInterval เกิดจากการคำนวนทำให้ทุกๆ frame ที่เกิดขึ้นมีค่าเท่ากันตลอด แต่ในความเป็นจริง fps ของ web browsers ไม่ได้มีค่าเฉลี่ยคงที่ ทำให้ในเวลาการใช้งาน setInterval จะทำให้ Animation ของเราไม่ลื่นไหล เกิดการ Frame skip ได้

สรุปได้ว่า

requestAnimationFrame มีประสิทธิภาพมากกว่า setInterval สำหรับการทำ Animation แม้ว่าอาจสังเกตความต่างเพียงเล็กน้อยแต่ถ้างานมีการ Animation มากก็อาจจะเห็นข้อผิดพลาดได้มากขึ้น

มาทดลองใช้งานกัน

<html><head>
<title></title>
<meta charset="utf-8">
</head>
<style>
canvas {
display: block;
margin: 0 auto;
}
div {
text-align: center;
vertical-align: middle;
font-size: 24px;
}
</style>
<body>
<canvas id="canvas" width="1000" height="50"></canvas>
<canvas id="canvas2" width="1000" height="50"></canvas>
<script>
var a = document.getElementById("canvas");
var b = document.getElementById("canvas2");
var ctx1 = a.getContext("2d");
var ctx2 = b.getContext("2d");
var x = 1;
requestAnimationFrame =
window.requestAnimationFrame ||
window.WebkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.mozRequestAnimationFrame;
function animate() {
ctx1.clearRect(0, 0, canvas.width, canvas.height);
ctx1.fillStyle = "Blue";
ctx1.fillRect(10, 0, x, 50);
ctx1.font = "20px Tahoma";
ctx1.fillStyle = "Black";
ctx1.fillText("requestAnimationFrame", x + 15, 50);
x++;
if (x > canvas.width) {
x = 0;
}
requestAnimationFrame(animate);
}
animate();
function animateSetInterval() {
ctx2.clearRect(0, 0, canvas.width, canvas.height);
ctx2.fillStyle = "Red";
ctx2.fillRect(10, 1, x, 50);
ctx2.font = "20px Tahoma";
ctx2.fillStyle = "Black";
ctx2.fillText("SetInterval", x + 15, 50);
x++;
if (x > canvas.width) {
x = 0;
}
}
setInterval(animateSetInterval, 1000 / 60);
</script>
</body>
</html>

--

--