Czy console.log zmniejszy wydajność wykonywania JavaScript?


102

Czy użycie funkcji debugowania console.logzmniejszy wydajność wykonywania JavaScript? Czy wpłynie to na szybkość wykonywania skryptów w środowiskach produkcyjnych?

Czy istnieje podejście do wyłączania dzienników konsoli w środowiskach produkcyjnych z jednej lokalizacji konfiguracji?


Wszystkie dotychczasowe odpowiedzi zakładają, że po prostu wyświetlasz komunikaty tekstowe. A co z wydajnością rejestrowania obiektów z możliwie dużymi strukturami obiektów? np. console.log (largeObj)?
PandaWood

Wysyłanie znacznej liczby obiektów do konsoli może spowodować, że ładowanie strony będzie trwało 3 sekundy w 30 sekund. Tylko przykład ...
Andrew

Prosty console.logtrwa ~ 50 ms
Pedram marandi

Odpowiedzi:


56

Jeśli masz zamiar mieć to w witrynie publicznej lub w czymś podobnym, każdy, kto ma niewielką wiedzę na temat korzystania z narzędzi programistycznych, może przeczytać twoje wiadomości debugowania. W zależności od tego, co rejestrujesz, może to nie być pożądane zachowanie.

Jednym z najlepszych podejść jest zawinięcie metody console.logw jedną z metod oraz sprawdzenie warunków i wykonanie jej. W kompilacji produkcyjnej można uniknąć posiadania tych funkcji. To pytanie dotyczące przepełnienia stosu zawiera szczegółowe informacje o tym, jak zrobić to samo za pomocą kompilatora Closure .

A więc odpowiadając na pytania:

  1. Tak, zmniejszy to prędkość, ale tylko nieznacznie.
  2. Ale nie używaj go, ponieważ czytanie dzienników jest zbyt łatwe.
  3. Odpowiedzi na to pytanie mogą dać ci wskazówki, jak usunąć je z produkcji.

dzięki, ale nadal zawijanie conosle.logbędzie nadal działało na zastąpioną funkcję, prawda?
Sudantha

15
Uwaga - używanie console.logdo rejestrowania obiektów powoduje wyciek pamięci, ponieważ przeglądarka zachowuje strukturę obiektów, aby umożliwić programistom rozszerzenie dziennika.
Shamasis Bhattacharya


9
„zbyt łatwo jest odczytać Twoje dzienniki” - jaki to problem? To JavaScript, mają już pełny dostęp do kodu źródłowego!
Quentin

5
Dla przypomnienia: właśnie odkryłem, że spamowanie console.log nawet tym samym statycznym tekstem (bez obiektu ani tablicy; dosłownie wystarczy, że console.log ('test') to zrobi) również powoduje spadek wydajności. Zwróciłem na to uwagę, gdy rejestrowałem „wywołanie” w funkcji, która została wywołana na setkach komponentów Reacta podczas ponownego renderowania. Sama obecność kodu logowania powodowała bardzo zauważalne zacinanie się podczas częstych aktualizacji.
Lew

82

W rzeczywistości console.logjest znacznie wolniejszy niż funkcja pusta. Uruchomienie tego testu jsPerf na moim Chrome 38 daje oszałamiające wyniki:

  • gdy konsola przeglądarki jest zamknięta, wywołanie console.logjest około 10000 razy wolniejsze niż wywołanie pustej funkcji,
  • i kiedy konsola jest otwarta, wywołanie jej jest nawet 100 000 razy wolniejsze .

Nie to, że zauważysz opóźnienie wydajności, jeśli masz rozsądną liczbę plików console.… wywołań uruchomionych raz (sto zajmie 2 ms przy mojej instalacji Chrome - lub 20 ms, gdy konsola jest otwarta). Ale jeśli wielokrotnie logujesz rzeczy do konsoli - na przykład podłączasz je do konsoli requestAnimationFrame- może to spowodować szarpnięcie.

Aktualizacja:

W tym teście sprawdziłem również pomysł niestandardowego „ukrytego dziennika” do produkcji - posiadającego zmienną, która przechowuje komunikaty dziennika, dostępną na żądanie. Okazuje się, że tak

  • około 1000 razy szybciej niż rodzimy console.log,
  • i oczywiście 10 000 razy szybciej, jeśli użytkownik ma otwartą konsolę.

1
Kiedy kompilator widzi pustą funkcję, nie wykonuje niczego, jeśli widzi linię do wykonania, będzie musiał uruchomić funkcję. kompilator po prostu nie uruchamia pustej, nieużywanej funkcji jako optymalizacji.
SidOfc

1
@SidneyLiebrand dzięki za informację, dobrze wiedzieć. Wyniki drugiego testu można zoptymalizować w taki sam sposób, jak console.loggdyby. Obie są funkcjami, które powodują skutki uboczne.
tomekwi

1
console.logSamo w sobie nie wpływa na wydajność w sposób, który zauważysz, chyba że powiążesz go z obsługą przewijania / zmiany rozmiaru. Nazywa się je dużo i jeśli twoja przeglądarka musi wysyłać tekst do konsoli, jak 30 / 60x na sekundę, może być brzydki. A potem jest ten błąd IE, który w ogóle nie pozwalał na to console.logprzy zamkniętej konsoli :(
SidOfc

1
Masz całkowitą rację - napisałem to również w mojej odpowiedzi. Z reguły staram się nie mieć wywołań konsoli w kodzie produkcyjnym. Ale wydajność nie jest powodem - raczej dlatego, że „laikowi zbyt łatwo jest odczytać twoje logi”, jak napisał @Ramesh.
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


10

Jeśli utworzysz skrót do konsoli we wspólnym podstawowym skrypcie, np .:

var con = console;

a następnie użyj con.log ("komunikat") lub con.error ("komunikat o błędzie") w całym kodzie, na produkcji możesz po prostu zmienić połączenie w głównej lokalizacji, aby:

var con = {
    log: function() {},
    error: function() {},
    debug: function() {}
}

16
brudny sposób:console.log = function(){}
br4nnigan

8

Czy użycie funkcji debugowania console.log zmniejszy wydajność wykonywania JavaScript? Czy wpłynie to na szybkość wykonywania skryptów w środowiskach produkcyjnych?

Oczywiście console.log()zmniejszy to wydajność programu, ponieważ wymaga czasu obliczeniowego.

Czy istnieje podejście do wyłączania dzienników konsoli w środowiskach produkcyjnych z jednej lokalizacji konfiguracji?

Umieść ten kod na początku skryptu, aby zastąpić standardową funkcję console.log pustą funkcją.

console.log = function () { };

2
Wydaje się, że jest to jedno z najprostszych rozwiązań wyłączania dzienników konsoli w środowisku produkcyjnym. Zastanawiasz się, dlaczego nie zwraca na to większej uwagi! Możemy kontrolować definicję tej pustej funkcji pod zmienną, którą możemy przełączać jako prawda / fałsz w zależności od środowiska, w którym pracujemy (prod lub dev)
Anshuman Manral

2
To świetna odpowiedź! Dzięki!
Reboot systemów

6

Każde wywołanie funkcji nieznacznie zmniejszy wydajność. Ale kilkaconsole.log z nich nie powinno przynieść zauważalnego efektu.

Jednak będzie generować niezdefiniowane błędy w starszych przeglądarkach, które nie obsługują console


3

Uderzenie w wydajność będzie minimalne, jednak w starszych przeglądarkach spowoduje błędy JavaScript, jeśli konsola przeglądarek użytkowników nie jest otwarta log is not a function of undefined. Oznacza to, że cały kod JavaScript po wywołaniu console.log nie zostanie wykonany.

Możesz utworzyć opakowanie, aby sprawdzić, czy window.consolejest to prawidłowy obiekt, a następnie wywołać w opakowaniu console.log. Coś tak prostego mogłoby zadziałać:

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

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

Oto skrzypce: http://jsfiddle.net/enDDV/


2

Zrobiłem ten test jsPerf: http://jsperf.com/console-log1337

Wydaje się, że nie trwa to dłużej niż inne wywołania funkcji.

A co z przeglądarkami, które nie mają interfejsu API konsoli? Jeśli potrzebujesz użyć console.log do debugowania, możesz dołączyć skrypt do wdrożenia produkcyjnego, aby zastąpić interfejs API konsoli, jak sugeruje Paul w swojej odpowiedzi.


jeśli mogę wybrać dwie odpowiedzi, to przejdzie do góry
Sudantha

1
Twój test nie tylko dodaje wywołanie console.log, ale także dwukrotnie wykonuje tę samą operację jquery. Stworzyłem następującą wersję twojego testu, mam nadzieję, że to pomoże: jsperf.com/console-log1337/7 PS: dzięki, nie wiedziałem o jsperf.com :)
dubrox

2
Wydaje się, że jest dużo wolniejsze niż zwykłe wywołanie funkcji. W bezpośrednim pojedynku wyniki są nieporównywalne: jsperf.com/console-log1337/14
tomekwi

1
Zła odpowiedź. Nawet w niewielkim stopniu poprawne. Głosy na myślenie życzeniowe, ponieważ @tomekwi pokazuje, że różnica jest niezwykła. Sam przeprowadziłem kilka testów w prawdziwym świecie i mogę bez cienia wątpliwości powiedzieć, że spamowanie console.log zdecydowanie powoduje spadek wydajności. Kilka dzienników tu i tam co sekundę lub dwie, nic wielkiego, ale rejestrują często (przy aktualizacjach ramek, ponownym renderowaniu masywnych komponentów), a różnica z console.log i bez niej jest noc i dzień.
Lew

1

Robię to w ten sposób, aby zachować oryginalny podpis metod konsolowych. We wspólnej lokalizacji, ładowanej przed jakimkolwiek innym JS:

var DEBUG = false; // or true 

Następnie w całym kodzie

if (DEBUG) console.log("message", obj, "etc");
if (DEBUG) console.warn("something is not right", obj, "etc");
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.