Développeur6 min de lecture

setInterval vs requestAnimationFrame : que choisir pour un minuteur ?

Pour un minuteur en JavaScript, setInterval est simple mais imprécis, requestAnimationFrame est fluide mais limité au taux de rafraîchissement. Comparatif.

Pour rafraîchir l'affichage d'un minuteur ou chronomètre en JavaScript, deux primitives s'offrent au développeur : setInterval et requestAnimationFrame. Aucune n'est universelle ; le bon choix dépend de la précision visée.

setInterval — simple mais imprécis

setInterval(updateDisplay, 1000);

Avantages — API directe, faible CPU, idéal pour rafraîchir une fois par seconde.

Limites :

  • L'intervalle réel peut dépasser 1000 ms si la page est chargée.
  • Throttlé à 1 Hz dans un onglet en arrière-plan.
  • Pas synchronisé avec le rafraîchissement écran : tearing possible.

requestAnimationFrame — fluide mais lié au refresh

function tick() {
  updateDisplay();
  requestAnimationFrame(tick);
}
tick();

Avantages — synchronisé sur le refresh (60 ou 120 Hz), animation fluide, économe en énergie sur écran inactif.

Limites :

  • Mis en pause complètement quand l'onglet est en arrière-plan.
  • Sur écran 60 Hz, ne tick que toutes les 16,6 ms.
  • API moins intuitive (récursion).

La règle d'or : ne JAMAIS dériver le temps du compteur

Quelle que soit la primitive, le compte à rebours doit se calculer par différence avec une heure cible :

const endTime = Date.now() + duration;
function tick() {
  const remaining = endTime - Date.now();
  render(remaining);
  if (remaining > 0) requestAnimationFrame(tick);
}

Si le navigateur saute un tick, le tick suivant rattrape automatiquement. Le compteur ne dérive jamais.

Recommandation

CasAPI
Minuteur affiché à la secondesetInterval(1000) + diff Date.now()
Chronomètre au centièmerequestAnimationFrame + diff performance.now()
Animation visuelle (barre)requestAnimationFrame
${CTA('chronometre/haute-precision', 'Voir un chrono haute précision')}

Pour aller plus loin