web-dev-qa-db-fra.com

SetInterval est-il consommateur d'UC?

J'ai lu quelque part que setInterval est gourmand en CPU. J'ai créé un script qui utilise setInterval et surveillé l'utilisation du processeur, mais je n'ai pas remarqué de changement. Je veux savoir s'il y a quelque chose qui m'a manqué.

Le code vérifie les modifications du hachage dans l'URL (contenu après #) toutes les 100 millisecondes et s'il a changé, chargez une page à l'aide d'AJAX. S'il n'a pas changé, rien ne se passe. Y aurait-il des problèmes de processeur avec cela.

59
Ryuku

Je ne pense pas que setInterval va intrinsèquement vous causer des problèmes de performances importants. Je soupçonne que la réputation peut provenir d'une époque antérieure, lorsque les processeurs étaient moins puissants.

Il existe cependant des moyens d'améliorer les performances, et il est probablement judicieux de les faire:

  1. Passez une fonction à setInterval, plutôt qu'une chaîne.
  2. Ayez le moins d'intervalles possible.
  3. Rendez les durées d'intervalle aussi longues que possible.
  4. Faites exécuter le code à chaque fois aussi court et simple que possible.

N'optimisez pas prématurément - ne vous compliquez pas la vie lorsqu'il n'y a pas de problème.

Une chose, cependant, que vous pouvez faire dans votre cas particulier est d'utiliser l'événement onhashchange, plutôt que des délais d'expiration, dans les navigateurs qui le prennent en charge.

59
lonesomeday

Je dirais plutôt que c'est tout le contraire. L'utilisation correcte de setTimeout et setInterval peut considérablement réduire l'utilisation du processeur du navigateur. Par exemple, utiliser setTimeout au lieu d'utiliser une boucle for ou while réduira non seulement l'intensité de l'utilisation du processeur, mais garantira également que le navigateur a la possibilité de mettre à jour la file d'attente de l'interface utilisateur plus souvent. Ainsi, les processus longs ne gèlent pas et ne bloquent pas l'expérience utilisateur.

Mais en général, l'utilisation de setInterval comme beaucoup sur votre site peut ralentir les choses. 20 intervalles de course simultanés avec un travail plus ou moins lourd affecteront le spectacle. Et puis encore .. vous pouvez vraiment gâcher n'importe quelle partie, je suppose que ce n'est pas un problème de setInterval.

..et au fait, vous n'avez pas besoin de vérifier le hachage comme ça. Il y a des événements pour ça:

onhashchange

se déclenche lorsqu'il y a eu un changement dans le hachage.

window.addEventListener('hashchange', function(e) {
    console.log('hash changed, yay!');
}, false);
14
jAndy

Non, setInterval ne consomme pas d'UC en soi. Si vous avez beaucoup d'intervalles exécutés sur des cycles très courts (ou une opération très complexe exécutée sur un intervalle modérément long), alors que peut facilement devenir gourmand en CPU, selon exactement ce que font vos intervalles et à quelle fréquence ils le font.

Je ne m'attendrais pas à voir des problèmes avec la vérification de l'URL toutes les 100 millisecondes sur un intervalle, bien que personnellement j'augmenterais l'intervalle à 250 millisecondes, juste parce que je ne m'attends pas à ce que la différence entre les deux soit perceptible par un type utilisateur et parce que j'essaie généralement d'utiliser les intervalles de temps d'attente les plus longs avec lesquels je pense que je peux m'en tirer, en particulier pour les choses qui devraient entraîner une interruption de service la plupart du temps.

9
aroth

Il y a un peu de marketing qui s'y fait sous le terme "CPU intensive". Ce que cela signifie vraiment, c'est "plus gourmand en CPU que certaines alternatives". Ce n'est pas "gourmand en CPU" comme dans "utilise beaucoup de puissance CPU comme le ferait un jeu ou un algorithme de compression".

Explication:

Une fois que le navigateur a cédé le contrôle, il s'appuie sur une interruption du système d'exploitation et du matériel sous-jacents pour recevoir le contrôle et émettre le rappel JavaScript. Le fait d'avoir des durées plus longues entre ces interruptions permet au matériel d'entrer dans des états de faible puissance, ce qui diminue considérablement la consommation d'énergie. Par défaut, le système d'exploitation Microsoft Windows et les processeurs basés sur Intel utilisent des résolutions de 15,6 ms pour ces interruptions (64 interruptions par seconde). Cela permet aux processeurs basés sur Intel d'entrer dans leur état d'alimentation le plus bas. Pour cette raison, les développeurs Web n'ont traditionnellement pu réaliser que 64 rappels par seconde lors de l'utilisation de setTimeout (0) lors de l'utilisation des navigateurs HTML4, y compris les éditions antérieures d'Internet Explorer et de Mozilla Firefox.

Au cours des deux dernières années, les navigateurs ont tenté d'augmenter le nombre de rappels par seconde que les développeurs JavaScript peuvent recevoir via les API setTimeout et setInterval en modifiant les paramètres du système Windows soucieux de leur puissance et en empêchant le matériel d'entrer dans des états de faible consommation. La spécification HTML5 est même allée jusqu'à recommander 250 rappels par seconde. Cette fréquence élevée peut entraîner une augmentation de 40% de la consommation d'énergie, affectant la durée de vie de la batterie, les dépenses d'exploitation et l'environnement. En outre, cette approche ne résout pas le problème de performances de base de l'amélioration de l'efficacité du processeur et de la planification.

De http://ie.Microsoft.com/testdrive/Performance/setImmediateSorting/Default.html

4
user703016

Dans votre cas, il n'y aura aucun problème. Mais si vous faites d'énormes animations dans le canevas ou travaillez avec webgl, il y aura des problèmes de processeur, donc pour cela, vous pouvez utiliser requestAnimationFrame.

Reportez-vous à ce lien À propos de requestAnimationFrame

3
Sarath

Le temps de fonction> le temps d'intervalle est mauvais, vous ne pouvez pas savoir quand le hoquet du processeur ou est lent et il se superpose aux fonctions en cours jusqu'à ce que le PC se fige. Utilisez settimeout ou encore mieux, process.nextick en utilisant un rappel dans un settimeout.