Wird console.log die Leistung der JavaScript-Ausführung verringern?

98

Wird die Verwendung der Debugging-Funktion console.logdie Ausführungsleistung von JavaScript verringern? Wird dies die Geschwindigkeit der Skriptausführung in Produktionsumgebungen beeinflussen?

Gibt es einen Ansatz zum Deaktivieren von Konsolenprotokollen in Produktionsumgebungen von einem einzigen Konfigurationsspeicherort aus?

Sudantha
quelle
Bei allen bisherigen Antworten wird davon ausgegangen, dass Sie lediglich Zeichenfolgenmeldungen ausgeben. Was ist mit der Leistung der Protokollierung von Objekten mit möglicherweise großen Objektstrukturen? zB console.log (largeObj)?
PandaWood
Durch die Ausgabe einer signifikanten Anzahl von Objekten an die Konsole kann das Laden von 3 Sekunden in 30 Sekunden umgewandelt werden. Nur ein Beispiel ...
Andrew
Eine einfache console.logdauert ~ 50ms
Pedram Marandi

Antworten:

55

Wenn Sie dies auf einer öffentlichen Website oder so etwas haben, kann jeder, der wenig über die Verwendung der Entwicklertools weiß, Ihre Debug-Meldungen lesen. Je nachdem, was Sie protokollieren, ist dies möglicherweise kein wünschenswertes Verhalten.

Einer der besten Ansätze besteht darin, die console.logMethode in eine Ihrer Methoden einzuschließen und sie auf Bedingungen zu überprüfen und auszuführen. In einem Produktions-Build können Sie diese Funktionen vermeiden. In dieser Frage zum Stapelüberlauf wird ausführlich erläutert, wie Sie dasselbe mit dem Closure-Compiler tun können .

Um Ihre Fragen zu beantworten:

  1. Ja, es wird die Geschwindigkeit reduzieren, wenn auch nur vernachlässigbar.
  2. Verwenden Sie es jedoch nicht, da es für eine Person zu einfach ist, Ihre Protokolle zu lesen.
  3. Die Antworten auf diese Frage geben Ihnen möglicherweise Hinweise, wie Sie sie aus der Produktion entfernen können.
Ramesh
quelle
danke, aber immer noch einpacken der conosle.logWille macht immer noch einen Treffer für die überschriebene Funktion, nicht wahr?
Sudantha
15
Nur ein Hinweis: Die Verwendung console.logzum Protokollieren von Objekten führt zu einem Speicherverlust, da der Browser die Objektstruktur beibehält, damit Entwickler das Protokoll erweitern können.
Shamasis Bhattacharya
3
@ Gajus Ihre Bearbeitung wird auf Meta
Infinite Recursion
8
"Es ist zu einfach für eine Person, Ihre Protokolle zu lesen" - Wie ist das ein Problem? Es ist JavaScript, sie haben bereits vollen Zugriff auf den Quellcode!
Quentin
4
Nur um sich einzuschalten: Ich habe gerade festgestellt, dass das Spammen des console.log selbst mit demselben statischen Text (kein Objekt oder Array; buchstäblich nur console.log ('test') würde dies tun) ebenfalls einen Leistungseinbruch verursacht. Dies wurde mir bewusst, als ich innerhalb einer Funktion "aufgerufen" protokollierte, die beim erneuten Rendern für Hunderte von React-Komponenten aufgerufen wurde. Das bloße Vorhandensein des Protokollierungscodes verursachte bei häufigen Aktualisierungen ein sehr merkliches Ruckeln.
Lev
80

Eigentlich console.logist viel langsamer als eine leere Funktion. Laufen diese jsPerf Test auf meinem Chrome 38 gibt erstaunliche Ergebnisse:

  • Wenn die Browserkonsole geschlossen ist, console.logist der Aufruf etwa 10 000 Mal langsamer als der Aufruf einer leeren Funktion.
  • und wenn die Konsole geöffnet ist, ist das Aufrufen bis zu 100.000 Mal langsamer .

Nicht, dass Sie die Leistungsverzögerung bemerken würden, wenn eine angemessene Anzahl von console.…Anrufen einmal ausgelöst wird (hundert werden bei meiner Chrome-Installation 2 ms dauern - oder 20 ms, wenn die Konsole geöffnet ist). Wenn Sie jedoch wiederholt requestAnimationFrameInhalte an der Konsole protokollieren, z. B. wenn Sie sie anschließen, kann dies zu Problemen führen.

Aktualisieren:

In diesem Test habe ich auch die Idee eines benutzerdefinierten „versteckten Protokolls“ für die Produktion überprüft - mit einer Variablen, die Protokollnachrichten enthält und bei Bedarf verfügbar ist. Es stellt sich heraus, zu sein

  • etwa 1 000 mal schneller als der Eingeborene console.log,
  • und natürlich 10 000 mal schneller, wenn der Benutzer seine Konsole geöffnet hat.
Tomekwi
quelle
1
Wenn ein Compiler eine leere Funktion sieht, führt er nichts aus, da er eine auszuführende Zeile sieht, in der er die Funktion ausführen muss. Der Compiler führt einfach keine leere, nicht verwendete Funktion als Optimierung aus.
SidOfc
1
@SidneyLiebrand danke für die Info, das ist gut zu wissen. Die Ergebnisse des zweiten Tests können auf die gleiche Weise optimiert werden console.log. Beide sind Funktionen, die Nebenwirkungen hervorrufen.
Tomékwi
1
console.logAn sich wirkt sich dies nicht wirklich auf die Leistung aus, die Sie bemerken werden, es sei denn, Sie binden es an einen Handler zum Scrollen / Ändern der Größe. Diese werden häufig aufgerufen, und wenn Ihr Browser 30 / 60x pro Sekunde Text an die Konsole senden muss, kann dies hässlich werden. Und dann gibt es diesen IE-Fehler, der es Ihnen überhaupt nicht erlaubt hat console.log, bei geschlossener Konsole zu sein :(
SidOfc
1
Sie haben absolut Recht - das habe ich auch in meiner Antwort geschrieben. Als Faustregel versuche ich, keine Konsolenaufrufe im Produktionscode zu haben. Aber Leistung ist nicht der Grund - es ist vielmehr so, dass "es für einen Laien zu einfach ist, Ihre Protokolle zu lesen", wie @Ramesh schrieb.
Tomekwi
1
logging-on x 3,179 ops/sec ±2.07% (56 runs sampled) logging-off x 56,058,330 ops/sec ±2.87% (56 runs sampled) logging-off-stringify x 1,812,379 ops/sec ±3.50% (58 runs sampled) log-nothing x 59,509,998 ops/sec ±2.63% (59 runs sampled)
Casey
11
const DEBUG = true / false
DEBUG && console.log('string')
Sergey Guns
quelle
Was für eine elegante Lösung!
Systems Rebooter
10

Wenn Sie in einem allgemeinen Kernskript eine Verknüpfung zur Konsole erstellen, z.

var con = console;

und verwenden Sie dann con.log ("message") oder con.error ("error message") im gesamten Code. Bei der Produktion können Sie con einfach am Kernspeicherort neu verkabeln, um:

var con = {
    log: function() {},
    error: function() {},
    debug: function() {}
}
sq2
quelle
16
der schmutzige Weg:console.log = function(){}
br4nnigan
7

Wird die Verwendung der Debugging-Funktion console.log die Leistung der JavaScript-Ausführung verringern? Wird dies die Geschwindigkeit der Skriptausführung in Produktionsumgebungen beeinflussen?

Dies console.log()verringert natürlich die Leistung Ihres Programms, da dies Rechenzeit in Anspruch nimmt.

Gibt es einen Ansatz zum Deaktivieren von Konsolenprotokollen in Produktionsumgebungen von einem einzigen Konfigurationsspeicherort aus?

Fügen Sie diesen Code am Anfang Ihres Skripts ein, um die Standardfunktion console.log in eine leere Funktion zu überschreiben.

console.log = function () { };
Heiliger Drache
quelle
2
Dies scheint eine der einfachsten Lösungen zum Deaktivieren von Konsolenprotokollen in der Produktionsumgebung zu sein. Ich frage mich, warum es nicht mehr Aufmerksamkeit hat! Wir können die Definition dieser leeren Funktion unter einer Variablen steuern, die wir je nach der Umgebung, an der wir arbeiten (prod oder dev), als wahr / falsch
umschalten können
2
Das ist so eine geniale Antwort! Vielen Dank!
Systems Rebooter
6

Jeder Funktionsaufruf verringert die Leistung geringfügig . Einige console.logsollten jedoch keine spürbare Wirkung haben.

In älteren Browsern, die dies nicht unterstützen, werden jedoch undefinierte Fehler ausgegeben console

Petah
quelle
3

Die Leistungseinbußen sind minimal, in älteren Browsern treten jedoch JavaScript-Fehler auf, wenn die Browserkonsole des Benutzers nicht geöffnet ist log is not a function of undefined. Dies bedeutet, dass der gesamte JavaScript-Code nach dem Aufruf von console.log nicht ausgeführt wird.

Sie können einen Wrapper erstellen, um zu überprüfen, ob window.consolees sich um ein gültiges Objekt handelt, und dann console.log im Wrapper aufrufen. So etwas Einfaches würde funktionieren:

window.log = (function(console) {
    var canLog = !!console;
    return function(txt) {
        if(canLog) console.log('log: ' + txt);
    };
})(window.console);

log('my message'); //log: my message

Hier ist eine Geige: http://jsfiddle.net/enDDV/

Paul
quelle
2

Ich habe diesen jsPerf-Test durchgeführt: http://jsperf.com/console-log1337

Es scheint nicht länger zu dauern als andere Funktionsaufrufe.

Was ist mit Browsern ohne Konsolen-API? Wenn Sie console.log zum Debuggen verwenden müssen, können Sie ein Skript in Ihre Produktionsbereitstellung aufnehmen, um die Konsolen-API zu überschreiben, wie Paul in seiner Antwort vorschlägt.

Jørgen
quelle
Wenn ich zwei Antworten auswählen kann, wird dies nach oben gehen
Sudantha
1
Ihr Test fügt nicht nur einen console.log-Aufruf hinzu, sondern führt dieselbe zweimalige Abfrageoperation auch zweimal aus. Ich habe die folgende Revision Ihres Tests erstellt, hoffe es hilft: jsperf.com/console-log1337/7 PS: Danke, ich wusste nichts über jsperf.com :)
Dubrox
2
Es scheint tatsächlich viel langsamer zu sein als ein normaler Funktionsaufruf. In einem direkten Duell sind die Ergebnisse unvergleichlich: jsperf.com/console-log1337/14
tomekwi
1
Falsche Antwort. Nicht einmal aus der Ferne korrekt. Wunschdenken Up-Votes als @tomekwi zeigt, dass der Unterschied bemerkenswert ist. Ich habe selbst mehrere Tests in der realen Welt durchgeführt und kann ohne jeden Zweifel sagen, dass Spam-Konsole.log definitiv einen Leistungseinbruch verursacht. Ein paar Protokolle hier und da jede oder jede zweite Sekunde, keine große Sache, aber häufig etwas protokollieren (bei Frame-Updates, erneutes Rendern von massiven Komponenten) und der Unterschied mit und ohne console.log ist Tag und Nacht.
Lev