javascriptrequestanimationframelit

What does calling requestAnimationFrame recursively do?


In this code block what does requestAnimationFrame do?

  tick() {
    if (this.running) {
      this.remaining = Math.max(0, this.end - Date.now());
      requestAnimationFrame(() => this.tick());
    }
  }

In other words what would be the difference between the above code an calling this.tick() outside of the requestAnimationFrame():

tick() {
    if (this.running) {
      this.remaining = Math.max(0, this.end - Date.now());
      this.tick()
    }
}

For reference this code sample is from the What is Lit web component timer example.


Solution

  • Using recursion without setTimeout or requestAnimationFrame just block the thread and hangs a browser. requestAnimationFrame schedules the callback just before repainting updated DOM and you can measure FPS like this:

    let running = false;
    let start1;
    let counter = 0;
    function tick() {
      if (running === false) return;
        counter++;
        $text.textContent = Math.round(1000/(performance.now()-start1)*counter) + 'Hz'
        requestAnimationFrame(tick);
    }
    function start() {
      if (running) return;
      running = true;
      counter = 0;
      start1 = performance.now();
      tick();
    }
    
    function stop() {
      $text.textContent = '';
      running = false
    }
    <button onclick="start()">Start</button>
    <button onclick="stop()">Stop</button>
    <div id="$text"></div>