Comment testez-vous les performances du code JavaScript?

337

Cycles du processeur, utilisation de la mémoire, temps d'exécution, etc.?

Ajouté: Existe-t-il un moyen quantitatif de tester les performances en JavaScript en plus de la simple perception de la vitesse d'exécution du code?

danmine
la source
Vous aimerez peut-être regarder le plugin YSlow pour Firefox.
Rob Wells
7
Cela ne fera que vous dire combien de temps il faut pour charger. Je pense que la question concernait davantage les performances lors de son exécution.
Sam Hasler
Si vous souhaitez instrumenter votre code pour la performance de la manière la plus courante (et la plus précise car vous pouvez affiner des fonctions spécifiques). Ce post a un bon exemple d'utilisation d'une minuterie (mais vous devriez vraiment regarder Performance.now si vous en avez l'occasion): albertech.blogspot.com/2015/07/…
jar
1
Pour des tests rapides et faciles dans votre navigateur, vous pouvez utiliser jsben.ch
EscapeNetscape

Réponses:

325

Les profileurs sont certainement un bon moyen d'obtenir des chiffres, mais d'après mon expérience, la performance perçue est tout ce qui compte pour l'utilisateur / client. Par exemple, nous avons eu un projet avec un accordéon Ext qui s'est développé pour afficher certaines données, puis quelques grilles Ext imbriquées. Tout était en fait rendu assez rapidement, aucune opération unique n'a pris beaucoup de temps, il y avait juste beaucoup d'informations rendues en même temps, donc cela semblait lent pour l'utilisateur.

Nous avons 'corrigé' cela, non pas en passant à un composant plus rapide, ou en optimisant une méthode, mais en rendant d'abord les données, puis en rendant les grilles avec un setTimeout. Ainsi, les informations sont apparues en premier, puis les grilles se mettraient en place une seconde plus tard. Dans l'ensemble, il a fallu un peu plus de temps pour le faire de cette façon, mais pour l'utilisateur, les performances perçues ont été améliorées.


Ces jours -ci , le profileur Chrome et d' autres outils sont universellement disponibles et faciles à utiliser, comme le sont console.time(), console.profile()et performance.now(). Chrome vous offre également une vue chronologique qui peut vous montrer ce qui tue votre fréquence d'images, où l'utilisateur peut attendre, etc.

Trouver la documentation de tous ces outils est vraiment facile, vous n'avez pas besoin d'une réponse SO pour cela. 7 ans plus tard, je répéterai toujours les conseils de ma réponse d'origine et je soulignerai que vous pouvez faire exécuter un code lent pour toujours là où un utilisateur ne le remarquera pas, et un code assez rapide qui s'exécute où il le fait, et il se plaindra du code assez rapide pas assez rapide. Ou que votre demande à votre API de serveur a pris 220 ms. Ou autre chose comme ça. Le fait demeure que si vous sortez un profileur et cherchez du travail à faire, vous le trouverez, mais ce n'est peut-être pas le travail dont vos utilisateurs ont besoin.

Noé
la source
3
C'est une étape de réglage fin après la mise en place des algorithmes bien connus et performants.
Rafael Xavier
1
C'est une très bonne réponse dans la mesure où elle prend une approche pratique dans la plupart des situations décrites dans la question. Cependant, cela ne répond pas à la question , qui demande s'il existe une autre façon de mesurer cela autre que la simple perception des utilisateurs. Le temps d'arrêt complet, par exemple lorsque les boutons sont gelés, peut toujours être mesuré en utilisant les méthodes de la réponse de pramodc et les commentaires qui y sont attachés.
RoboticRenaissance
202

Je suis d'accord que la performance perçue est vraiment tout ce qui compte. Mais parfois, je veux juste savoir quelle méthode de faire quelque chose est plus rapide. Parfois, la différence est ÉNORME et mérite d'être connue.

Vous pouvez simplement utiliser des minuteries javascript. Mais j'obtiens généralement des résultats beaucoup plus cohérents en utilisant les méthodes devTool natives de Chrome (maintenant également dans Firefox et Safari) console.time()etconsole.timeEnd()

Exemple d'utilisation:

var iterations = 1000000;
console.time('Function #1');
for(var i = 0; i < iterations; i++ ){
    functionOne();
};
console.timeEnd('Function #1')

console.time('Function #2');
for(var i = 0; i < iterations; i++ ){
    functionTwo();
};
console.timeEnd('Function #2')

Les résultats ressemblent à ceci

Mise à jour (04/04/2016):

Chrome Canary a récemment ajouté le niveau de profilage de l'onglet des sources des outils de développement qui vous permet de voir exactement combien de temps chaque ligne a pris pour s'exécuter! entrez la description de l'image ici

Jose Browne
la source
Oui, l'un des charmes de celui-ci est qu'il est rapide et facile à mettre en œuvre. Je me demande, est-ce que la journalisation en soi prendra une partie des performances de l'exécution javascript. Disons que nous avons une boucle dans un jeu et qu'elle génère plusieurs lignes de journal. Par exemple, une fois par seconde pendant 5 minutes, soit 300 lignes. Quelqu'un sait?
K. Kilian Lindberg
Est-ce toujours opérationnel? Ne pas apparaître dans Chrome.
Statistiques d'apprentissage par l'exemple du
2
Yup travaille toujours pour moi. developer.chrome.com/devtools/docs/console-api#consoletimelabel
Jose Browne
@ K.KilianLindberg La journalisation prendra toujours du temps à cause des performances, comme tout code, mais a) elle sera cohérente dans vos tests et b) vous ne devriez pas vous connecter à la console en code live. Après avoir testé sur ma machine, l'enregistrement du temps n'est qu'une fraction d'une MS, mais il s'additionnera plus vous le ferez.
Polyducks
92

Nous pouvons toujours mesurer le temps pris par n'importe quelle fonction par simple objet date .

var start = +new Date();  // log start timestamp
function1();
var end =  +new Date();  // log end timestamp
var diff = end - start;
pramodc84
la source
10
Notez que cette solution renvoie le diff en millisecondes
Chris Bier
16
L'utilisation de Date () est déconseillée car le temps en millisecondes peut varier en fonction des facteurs du système. Utilisez plutôt console.time () et console.timeEnd (). Voir la réponse de JQuery Lover pour plus de détails.
mbokil
44
Encore mieux, utilisezperformance.now()
edan
1
Avant d'utiliser performance.now (), veuillez vérifier la compatibilité du navigateur. developer.mozilla.org/en-US/docs/Web/API/Performance/…
AR_HZ
La date n'est pas vraiment représentative du temps écoulé. Consultez cet article dessus: sitepoint.com/measuring-javascript-functions-performance . Performance.now () est un horodatage plus précis.
Millsionaire
61

Essayez jsPerf . Il s'agit d'un outil de performance javascript en ligne pour comparer et comparer des extraits de code. Je l'utilise tout le temps.

Se détendre
la source
1
Étant donné que jsPerf est en panne pour le moment , benchmarkjs est facile à utiliser à la place .
mucaho
Je le recommande également car il donne une mesure ops / sec (il exécute votre code plusieurs fois)
Richard
+9001 (c'est plus de neuf mille;) pour jsPerf. Je l'utilise régulièrement de la même manière que %timeitdans un ipythonshell REPL pour le code Python.
amcgregor
37

La plupart des navigateurs implémentent désormais une synchronisation haute résolution performance.now(). Il est supérieur aux new Date()tests de performances car il fonctionne indépendamment de l'horloge système.

Usage

var start = performance.now();

// code being timed...

var duration = performance.now() - start;

Références

Daniel Imms
la source
2
Encore mieux serait d'utiliser l' API User Timing , qui s'appuie sur performance.now().
Chris
30

JSLitmus est un outil léger pour créer des tests de référence JavaScript ad-hoc

Examinons les performances entre function expressionet function constructor:

<script src="JSLitmus.js"></script>
<script>

JSLitmus.test("new Function ... ", function() { 
    return new Function("for(var i=0; i<100; i++) {}"); 
});

JSLitmus.test("function() ...", function() { 
       return (function() { for(var i=0; i<100; i++) {}  });
});

</script>

Ce que je l'ai fait ci - dessus est de créer un function expressionet function constructoreffectuer la même opération. Le résultat est le suivant:

Résultat de performance FireFox

Résultat de performance FireFox

Résultat de performance IE

Résultat de performance IE

Ramiz Uddin
la source
La page JSLitmus liée contient des liens de téléchargement rompus. J'ai trouvé JSLitmus (pour les navigateurs) et jslitmus (pour NodeJS, en minuscules!).
Rob W
16

Certaines personnes proposent des plug-ins et / ou des navigateurs spécifiques. Je ne le ferais pas car ils ne sont vraiment utiles que pour cette seule plate-forme; une exécution de test sur Firefox ne se traduira pas correctement en IE7. Étant donné que 99,999999% des sites sont visités par plusieurs navigateurs, vous devez vérifier les performances sur toutes les plates-formes populaires.

Ma suggestion serait de garder cela dans le JS. Créez une page d'analyse comparative avec tous vos tests JS et chronométrez l'exécution. Vous pourriez même l'avoir AJAX-poster les résultats pour vous de le garder entièrement automatisé.

Ensuite, rincez et répétez sur différentes plates-formes.

Oli
la source
5
c'est vrai, mais les profileurs sont bons en cas de problème de codage qui n'a rien à voir avec un problème spécifique au navigateur.
John Boker,
1
Sûr! Oui, ils détectent les problèmes généraux de "mauvais codage" et certains problèmes spécifiques sont parfaits pour effectuer le débogage, mais pour les tests de cas d'utilisation généraux, vous bénéficierez de quelque chose qui s'exécute sur toutes les plates-formes.
Oli
2
+1 sur la note que cela est vrai, mais avoir un profileur comme Firebug est toujours génial, sinon essentiel, pour trouver des goulots d'étranglement.
Pekka
1
" Considérant 99,999999% des sites ... " Je pense que vous avez inventé cela:: / /
RobG
@RobG Je surestime peut-être une décimale ou deux, mais l'idée que votre plateforme de développement ne sera probablement pas identique à votre plateforme de déploiement tient.
Oli
11

J'ai un petit outil où je peux rapidement exécuter de petits cas de test dans le navigateur et obtenir immédiatement les résultats:

Test de vitesse JavaScript

Vous pouvez jouer avec le code et découvrir quelle technique est la meilleure dans le navigateur testé.

DUzun
la source
Merci, c'est exactement ce que je cherchais.
Joseph Sheedy
9

Voici une fonction simple qui affiche le temps d'exécution d'une fonction passée:

var perf = function(testName, fn) {
    var startTime = new Date().getTime();
    fn();
    var endTime = new Date().getTime();
    console.log(testName + ": " + (endTime - startTime) + "ms");
}
Bunz
la source
4

Réponse rapide

Sur jQuery (plus spécifiquement sur Sizzle), nous utilisons ceci (master de paiement et open speed / index.html sur votre navigateur), qui à son tour utilise benchmark.js . Il est utilisé pour tester les performances de la bibliothèque.

Longue réponse

Si le lecteur ne connaît pas la différence entre le benchmark, la charge de travail et les profileurs, lisez d'abord quelques fondements de test de performances dans la section "Readme 1st" de spec.org . C'est pour les tests du système, mais la compréhension de ces fondements aidera également les tests de performance JS. Quelques faits saillants:

Qu'est-ce qu'une référence?

Une référence est "une norme de mesure ou d'évaluation" (Webster's II Dictionary). Un benchmark informatique est généralement un programme informatique qui effectue un ensemble d'opérations strictement défini - une charge de travail - et renvoie une certaine forme de résultat - une métrique - décrivant le fonctionnement de l'ordinateur testé. Les indicateurs de référence informatiques mesurent généralement la vitesse: à quelle vitesse la charge de travail a-t-elle été accomplie; ou débit: combien d'unités de charge de travail par unité de temps ont été réalisées. L'exécution du même banc d'essai sur plusieurs ordinateurs permet de faire une comparaison.

Dois-je comparer ma propre application?

Idéalement, le meilleur test de comparaison pour les systèmes serait votre propre application avec votre propre charge de travail. Malheureusement, il est souvent impossible d'obtenir une large base de mesures fiables, reproductibles et comparables pour différents systèmes en utilisant votre propre application avec votre propre charge de travail. Les problèmes peuvent inclure la génération d'un bon cas de test, des problèmes de confidentialité, des difficultés à garantir des conditions comparables, du temps, de l'argent ou d'autres contraintes.

Si ce n'est pas ma propre application, alors quoi?

Vous pouvez envisager d'utiliser des repères standardisés comme point de référence. Idéalement, un référentiel normalisé sera portable et peut déjà avoir été exécuté sur les plates-formes qui vous intéressent. Cependant, avant de considérer les résultats, vous devez vous assurer que vous comprenez la corrélation entre vos besoins applicatifs / informatiques et ce que le repère mesure. Les repères sont-ils similaires aux types d'applications que vous exécutez? Les charges de travail ont-elles des caractéristiques similaires? Sur la base de vos réponses à ces questions, vous pouvez commencer à voir comment l'indice de référence peut se rapprocher de votre réalité.

Remarque: Une référence normalisée peut servir de point de référence. Néanmoins, lorsque vous effectuez une sélection de fournisseur ou de produit, SPEC ne prétend pas qu'une référence normalisée puisse remplacer la comparaison de votre propre application réelle.

Test de performance JS

Idéalement, le meilleur test de performance serait d'utiliser votre propre application avec votre propre charge de travail en changeant ce dont vous avez besoin pour tester: différentes bibliothèques, machines, etc.

Si cela n'est pas possible (et ce n'est généralement pas le cas). Première étape importante: définir votre charge de travail. Il doit refléter la charge de travail de votre application. Dans cet exposé , Vyacheslav Egorov parle de charges de travail merdiques que vous devriez éviter.

Ensuite, vous pouvez utiliser des outils tels que benchmark.js pour vous aider à collecter des mesures, généralement la vitesse ou le débit. Sur Sizzle, nous souhaitons comparer la façon dont les correctifs ou les modifications affectent les performances systémiques de la bibliothèque.

Si quelque chose fonctionne vraiment mal, votre prochaine étape consiste à rechercher les goulots d'étranglement.

Comment trouver les goulots d'étranglement? Profileurs

Quelle est la meilleure façon de profiler l'exécution javascript?

Rafael Xavier
la source
3

Je trouve que le temps d'exécution est la meilleure mesure.

pdavis
la source
Par opposition à quoi? Je ne suis pas sûr de comprendre.
Pekka
Par opposition à la question des affiches d'origine: "Cycles du processeur, utilisation de la mémoire, temps d'exécution, etc.?"
snicker
3

Vous pouvez utiliser console.profile dans firebug

Willem de Wit
la source
2

Je teste généralement les performances javascript, la durée d'exécution du script. jQuery Lover a fourni un bon lien d'article pour tester les performances du code javascript , mais l'article montre uniquement comment tester la durée de fonctionnement de votre code javascript. Je recommanderais également de lire l'article intitulé "5 conseils pour améliorer votre code jQuery tout en travaillant avec d'énormes ensembles de données".

Ouzbekjon
la source
2

Voici une classe réutilisable pour les performances temporelles. Un exemple est inclus dans le code:

/*
     Help track time lapse - tells you the time difference between each "check()" and since the "start()"

 */
var TimeCapture = function () {
    var start = new Date().getTime();
    var last = start;
    var now = start;
    this.start = function () {
        start = new Date().getTime();
    };
    this.check = function (message) {
        now = (new Date().getTime());
        console.log(message, 'START:', now - start, 'LAST:', now - last);
        last = now;
    };
};

//Example:
var time = new TimeCapture();
//begin tracking time
time.start();
//...do stuff
time.check('say something here')//look at your console for output
//..do more stuff
time.check('say something else')//look at your console for output
//..do more stuff
time.check('say something else one more time')//look at your console for output
Shawn Dotey
la source
1

UX Profiler aborde ce problème du point de vue de l'utilisateur. Il regroupe tous les événements du navigateur, l'activité du réseau, etc. causés par une action de l'utilisateur (cliquez) et prend en compte tous les aspects tels que la latence, les délais d'attente, etc.

Konstantin Triger
la source
1

Je cherchais quelque chose de similaire mais j'ai trouvé ça.

https://jsbench.me/

Il permet une comparaison côte à côte et vous pouvez également partager les résultats.

Ste
la source
0

La règle d'or est de ne verrouiller en aucun cas le navigateur de votre utilisateur. Après cela, je regarde généralement le temps d'exécution, suivi de l'utilisation de la mémoire (à moins que vous ne fassiez quelque chose de fou, auquel cas cela pourrait être une priorité plus élevée).

William Keller
la source
0

Les tests de performances sont devenus un mot à la mode ces derniers temps, mais cela ne veut pas dire que les tests de performances ne sont pas un processus important dans l'AQ ou même après l'expédition du produit. Et pendant que je développe l'application, j'utilise de nombreux outils différents, certains d'entre eux mentionnés ci-dessus, comme le Chrome Profiler, je regarde généralement un SaaS ou quelque chose d'opensource que je peux utiliser et l'oublier jusqu'à ce que je reçoive cette alerte disant que quelque chose a mal tourné .

Il existe de nombreux outils impressionnants qui vous aideront à garder un œil sur les performances sans vous faire sauter à travers des cerceaux juste pour configurer des alertes de base. Voici quelques-unes qui, je pense, méritent d'être vérifiées par vous-même.

  1. Sematext.com
  2. Datadog.com
  3. Uptime.com
  4. Smartbear.com
  5. Solarwinds.com

Pour essayer de brosser un tableau plus clair, voici un petit tutoriel sur la façon de configurer la surveillance pour une application React.

John Demian
la source
-1

Il s'agit d'un bon moyen de collecter des informations sur les performances de l'opération spécifique.

start = new Date().getTime(); 
for (var n = 0; n < maxCount; n++) {
/* perform the operation to be measured *//
}
elapsed = new Date().getTime() - start;
assert(true,"Measured time: " + elapsed);
user2601995
la source