Introduction and comparison of advantages and disadvantages of requestAnimationFrame, setInterval and setTimeout in front-end development

一、requestAnimationFrame()

requestAnimationFrame is a technology that implements animation loops in browsers. It periodically calls a specified callback function through a timer mechanism to achieve the effect of web page animation. Different from traditional setInterval and setTimeout, requestAnimationFrame has better browser compatibility, more precise timing control and better performance.

Use requestAnimationFrame to encapsulate the drawing operation of each frame of animation into a callback function, and pass this callback function to the requestAnimationFrame function. When the browser is ready to draw the next frame, it will automatically call this callback function, thus realizing the animation cycle.

Notice:
  • The parameter of the callback function is a timestamp, which indicates the time from the current time point to the completion of page loading.
  • The execution interval of the callback function is not fixed and is scheduled by the browser based on rendering performance and other factors.
  • If requestAnimationFrame is not called again for a while, the animation stops.
  • When the browser is inactive, the callback function of requestAnimationFrame will not be executed.
  • requestAnimationFrame can be used to implement various types of animation effects, including DOM animation, Canvas animation, SVG animation, WebGL animation, etc.
grammar:
requestAnimationFrame(callback);

Parameters
callback: The function called to update the animation frame before the next redraw (the callback function mentioned above). The callback function will be passed in the DOMHighResTimeStamp parameter, which is the same as the return value of performance.now(). It indicates the moment when requestAnimationFrame() starts executing the callback function.

Return value
A long integer, request ID, which is the only identifier in the callback list. It is a non-zero value and has no other meaning. You can pass this value to window.cancelAnimationFrame() to cancel the callback function.

Example

In this example, we define a function called updateAnimation to update the animation state of an element. We then use the requestAnimationFrame function to start the animation, which adds the updateAnimation function to the queue to be executed before the next redraw of the browser. In the updateAnimation function, we call the requestAnimationFrame function again to request that the function be executed again before the next redraw, thus forming a loop that continuously updates the animation state.

// 定义一个更新动画的函数  
function updateAnimation() {  
  // 更新动画状态  
  const animationElement = document.getElementById('animation');  
  animationElement.style.left = (animationElement.offsetLeft + 10) + 'px';  
  
  // 请求下一次重绘之前再次执行该函数  
  requestAnimationFrame(updateAnimation);  
}  
  
// 启动动画  
requestAnimationFrame(updateAnimation);
2. setTimeout()

The setTimeout() method is used to specify that a function or string will be executed after the specified number of milliseconds. It returns an integer representing the timer number. This value can be passed to clearTimeout() to cancel the execution of this function.

In the following code, the console first outputs 0, and after about 1000ms or 1s, it outputs the return value 1 of the timer setTimeout() method.

var Timer = setTimeout(function(){
    console.log(Timer);
},1000);
console.log(0);

If the second parameter of setTimeout is omitted, this parameter defaults to 0

In fact, in addition to the first two parameters, the setTimeout() method also allows adding more parameters, which will be passed into the function in the timer
In the following code, After about 1000ms or 1s, the console outputs 2. However, IE9-browser only allows setTimeout to have two parameters and does not support more parameters. NaN will be output on the console

setTimeout(function(a,b){
  console.log(a+b);
},1000,1,1);
Example

User-defined callback function, usually triggered before the browser's default action. For example, if the user enters text in the input box, the keypress event will be triggered before the browser receives the text. Therefore, the following callback function does not serve the purpose

<input type="text" id="myInput">
<script>
var myInput = document.getElementById('myInput')
myInput.onkeypress = function(event) {
  this.value = this.value.toUpperCase();
}
</script>

The above code wants to convert characters to uppercase immediately after the user enters text. But in fact, it can only convert the previous character to uppercase, because the browser has not received the text yet, so this.value cannot get the latest entered character.

The above code can only work if it is rewritten with setTimeout

<input type="text" id="myInput">
<script>
var myInput = document.getElementById('myInput')
myInput.onkeypress = function(event) {
    setTimeout(function(){
        myInput.value = myInput.value.toUpperCase();
    });
}
</script>
clearTimeout()

The setTimeout function returns an integer value representing the counter number. Pass the integer to the clearTimeout function to cancel the corresponding timer.

Generally speaking, the integer value returned by setTimeout is continuous, that is, the integer value returned by the second setTimeout method is 1 greater than the first integer value.

3. setInterval()

setInterval is a JavaScript function that is used to call a function or evaluate an expression at a specified period (in milliseconds). It can execute code at relatively accurate time intervals and can be used to create scheduled tasks or animations.

The usage of setInterval is exactly the same as that of setTimeout. The only difference is that setInterval specifies that a certain task should be executed every once in a while, that is, unlimited scheduled execution.

The HTML5 standard stipulates that the minimum time interval for setTimeout is 4 milliseconds; the minimum interval time for setInterval is 10 milliseconds. That is to say, the time interval less than 10 milliseconds will be adjusted to 10 milliseconds.

The refresh rate of most computer monitors is 60HZ, which is roughly equivalent to redrawing 60 times per second. Therefore, the optimal loop interval for the smoothest animation effect is 1000ms/60, which is approximately equal to 16.6ms

In order to save power, the browser will expand the time interval to 1000 milliseconds for pages that are not in the current window. In addition, if the laptop is on battery power, Chrome and IE10+ browsers will switch the time interval to the system timer, which is approximately 16.6 milliseconds

The setInterval method will return an ID value, which can be used to stop the timer. You can use the clearInterval(id) function to stop the specified timer, where id is the ID value returned by setInterval.

The working principle of setInterval is that when the specified time interval passes, it will automatically execute the specified code or function once, and then wait for the next time interval. This process will repeat until clearInterval is called or the window is closed.

It should be noted that setInterval does not guarantee that the code or function will be executed strictly according to the specified time interval. If the execution time of the code or function is too long, or when processing some asynchronous operations, the actual execution time interval may deviate from the specified time interval. In addition, insufficient browser or computer performance may cause delays in the execution of the timer.

Example

In this example, we first define a variable named intervalId to store the ID value returned by setInterval. We then use the setInterval function to execute an anonymous function that takes an element and updates the element's text content with the current time. The setInterval function will execute this function before each browser redraw, and will wait 1 second between each execution. Finally, we use the setTimeout function to stop the timer after 10 seconds.

// 每隔1秒钟更新一次文本内容  
const intervalId = setInterval(function() {  
  const timeElement = document.getElementById('time');  
  const currentTime = new Date().toLocaleTimeString();  
  timeElement.textContent = currentTime;  
}, 1000);  
  
// 在10秒钟后停止定时器  
setTimeout(function() {  
  clearInterval(intervalId);  
}, 10000);

setInterval can be used in a variety of scenarios, such as updating data regularly, triggering events regularly, creating animations, etc. For example, you can use setInterval to automatically update the status of UI components at certain intervals, or automatically send HTTP requests to obtain data at certain intervals.

4. Comparison
working principle:
  • setTimeout: This function will put the code or function to be executed into the event loop queue, wait for the current code to complete execution, and then wait for the specified time to execute again. If a timer is set, the code will be executed at regular intervals until clearTimeout is called or the window is closed.

  • setInterval: Similar to setTimeout, setInterval also puts the code or function to be executed into the event loop queue, but it will be executed repeatedly after the specified time interval until clearInterval is called or the window is closed. In other words, setInterval will continue to call the function until it is canceled.

  • requestAnimationFrame: This function works slightly differently than setInterval and setTimeout. It adds the callback function to the queue to be executed before the next redraw of the browser. The purpose of this is to ensure the smoothness of the animation, because the browser will automatically optimize this API, and the callback function will only be executed when the browser is active and the page is visible. In addition, requestAnimationFrame automatically matches the time interval based on the system's refresh rate, ensuring that the time between each frame of animation is as accurate as possible.

the difference:
  • Execution timing: requestAnimationFrame is an API provided by the browser, which will execute the callback function before the next redraw of the browser. This means it ensures smooth animations and automatically matches the system's refresh rate. In contrast, setInterval and setTimeout execute callback functions after a specified interval, regardless of whether the browser is active or otherwise operating.

  • Performance optimization: requestAnimationFrame is automatically optimized by the browser, and the callback function will only be executed when the browser is active and the page is visible. This saves CPU, GPU and memory usage, especially on mobile devices. In contrast, setInterval and setTimeout are not automatically optimized. If the page is hidden or invisible, they will continue to execute the callback function, which may lead to a waste of resources.

  • Callback function execution time: The callback function of requestAnimationFrame will be executed before the next redraw of the browser, so it can ensure that the execution time of the callback function is relatively accurate. In contrast, the callback function execution time of setInterval and setTimeout depends on the queue and execution time in the browser event loop, so there may be a certain delay.

  • Stop operation: The callback function of requestAnimationFrame will only be executed once before the next redraw of the browser, so the operation can be stopped by clearing the callback function in the queue. In contrast, setInterval and setTimeout will continuously execute the callback function until clearInterval or clearTimeout is called or the page is closed.

  • Function throttling: In high-frequency events (resize, scroll, etc.), in order to prevent multiple function executions within a refresh interval, use requestAnimationFrame to ensure that the function is only executed once within each refresh interval, thus ensuring smoothness performance, and can also better save the cost of function execution.

Application scenarios
  • setTimeout: can be used to delay certain operations after the web page is loaded, such as loading page content, initializing components, etc. It can also be used to trigger certain operations regularly, such as sending data regularly, checking tasks regularly, etc.

  • setInterval: often used for operations that need to be performed periodically, such as regularly updating data, regularly triggering events, etc. On the web side, if the list needs to be updated regularly, you can use setInterval to regularly obtain the list request. In addition, if you need to clear the scheduled task under certain circumstances, you can use clearInterval to stop the timer.

  • requestAnimationFrame: mainly used to achieve smooth animation effects. It will execute the specified function before the next redraw of the browser, avoiding performance problems caused by frequent redraws. requestAnimationFrame automatically matches the system's refresh rate, ensuring that the time between each frame of animation is as accurate as possible. When repeated triggering is required, using requestAnimationFrame can avoid mutual interference caused by continuous calls.

5. Example

Now use the three methods setInterval, setTimeout and requestAnimationFrame to create a simple progressive effect.

<div style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;" id="div">0%</div>

<button id="btn">run</button>

<script>
    var timer;
    var btn = document.getElementById('btn')
    var myDiv = document.getElementById('div')
    
    // 1.requestAnimationFrame
    btn.onclick = function () {
        myDiv.style.width = '0';
        cancelAnimationFrame(timer);
        timer = requestAnimationFrame(function fn() {
            if (parseInt(myDiv.style.width) < 500) {
                myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
                myDiv.innerHTML = parseInt(myDiv.style.width) / 5 + '%';
                timer = requestAnimationFrame(fn);
            } else {
                cancelAnimationFrame(timer);
            }
        });
    }

    // 2.setInterval
    btn.onclick = function () {
        clearInterval(timer);
        myDiv.style.width = '0';
        timer = setInterval(function () {
            if (parseInt(myDiv.style.width) < 500) {
                myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
                myDiv.innerHTML = parseInt(myDiv.style.width) / 5 + '%';
            } else {
                clearInterval(timer);
            }
        }, 16);
    }

    // 3.setTimeout
    btn.onclick = function () {
        clearTimeout(timer);
        myDiv.style.width = '0';
        timer = setTimeout(function fn() {
            if (parseInt(myDiv.style.width) < 500) {
                myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
                myDiv.innerHTML = parseInt(myDiv.style.width) / 5 + '%';
                timer = setTimeout(fn, 16);
            } else {
                clearTimeout(timer);
            }
        }, 16);
    }
</script>

Guess you like

Origin blog.csdn.net/shanghai597/article/details/134778194