console.log จะลดประสิทธิภาพการดำเนินการของ JavaScript หรือไม่


106

การใช้คุณลักษณะการดีบักจะconsole.logลดประสิทธิภาพการดำเนินการของ JavaScript หรือไม่ จะส่งผลต่อความเร็วของการเรียกใช้สคริปต์ในสภาพแวดล้อมการผลิตหรือไม่

มีวิธีปิดใช้งานบันทึกคอนโซลในสภาพแวดล้อมการใช้งานจริงจากตำแหน่งคอนฟิกูเรชันเดียวหรือไม่?


ตอนนี้คำตอบทั้งหมดสมมติว่าคุณเป็นเพียงการส่งออกข้อความสตริง สิ่งที่เกี่ยวกับประสิทธิภาพของการบันทึกวัตถุที่มีโครงสร้างวัตถุขนาดใหญ่? เช่น console.log (largeObj)?
PandaWood

การส่งออกออบเจ็กต์จำนวนมากไปยังคอนโซลสามารถเปลี่ยนการโหลดหน้า 3 วินาทีให้เป็น 30 วินาที แค่ตัวอย่าง ...
Andrew

ที่เรียบง่ายconsole.logใช้เวลา ~ 50ms
Pedram Marandi

คำตอบ:


59

หากคุณกำลังจะมีสิ่งนี้ในไซต์สาธารณะหรือบางสิ่งบางอย่างใครก็ตามที่มีความรู้เพียงเล็กน้อยเกี่ยวกับการใช้เครื่องมือสำหรับนักพัฒนาสามารถอ่านข้อความแก้ไขข้อบกพร่องของคุณได้ สิ่งนี้อาจไม่ใช่พฤติกรรมที่พึงประสงค์ทั้งนี้ขึ้นอยู่กับสิ่งที่คุณกำลังบันทึก

วิธีที่ดีที่สุดวิธีหนึ่งคือการconsole.logรวมวิธีการใดวิธีการหนึ่งของคุณและคุณสามารถตรวจสอบเงื่อนไขและดำเนินการได้ที่ไหน ในรุ่นการผลิตคุณสามารถหลีกเลี่ยงการมีฟังก์ชันเหล่านี้ได้ นี้คำถามกองมากเกินพูดในรายละเอียดเกี่ยวกับวิธีการที่จะทำเช่นเดียวกันโดยใช้คอมไพเลอร์ปิด

ดังนั้นเพื่อตอบคำถามของคุณ:

  1. ใช่มันจะลดความเร็วแม้เพียงเล็กน้อย
  2. แต่อย่าใช้เพราะมันง่ายเกินไปสำหรับคนที่จะอ่านบันทึกของคุณ
  3. คำตอบสำหรับคำถามนี้อาจให้คำแนะนำเกี่ยวกับวิธีนำคำถามออกจากการผลิต

ขอบคุณ แต่ยังคงตัดconosle.logเจตจำนงยังคงสร้างความนิยมให้กับฟังก์ชันที่ถูกลบล้างอยู่ใช่หรือไม่
Sudantha

15
เพียงบันทึก - ใช้ console.logบันทึกวัตถุจะทำให้หน่วยความจำรั่วเนื่องจากเบราว์เซอร์ยังคงรักษาโครงสร้างวัตถุไว้เพื่อให้นักพัฒนาสามารถขยายบันทึกได้
Shamasis Bhattacharya


9
"มันง่ายเกินไปสำหรับคนที่จะอ่านบันทึกของคุณ" - ปัญหานี้เป็นอย่างไร มันเป็น JavaScript พวกเขาสามารถเข้าถึงซอร์สโค้ดได้อย่างสมบูรณ์!
Quentin

5
เพียงเพื่อตีระฆัง: ฉันเพิ่งค้นพบว่าสแปม console.log แม้จะมีข้อความคงที่เหมือนกัน (ไม่มีวัตถุหรืออาร์เรย์เพียงแค่ console.log ('test') ก็ทำได้) ก็ทำให้เกิดประสิทธิภาพเช่นกัน สิ่งนี้เกิดขึ้นในขณะที่ฉันกำลังบันทึก "เรียก" ภายในฟังก์ชันที่เรียกใช้กับส่วนประกอบ React หลายร้อยรายการในระหว่างการแสดงผลซ้ำ การมีรหัสการบันทึกเพียงอย่างเดียวทำให้เกิดการกระตุกอย่างเห็นได้ชัดในระหว่างการอัปเดตบ่อยๆ
Lev

86

อันที่จริงconsole.logช้ากว่าฟังก์ชันว่างมาก การเรียกใช้การทดสอบ jsPerf นี้บน Chrome 38 ของฉันให้ผลลัพธ์ที่น่าทึ่ง:

  • เมื่อปิดคอนโซลเบราว์เซอร์การโทรconsole.logจะช้ากว่าการเรียกฟังก์ชันว่างประมาณ 10,000 เท่า
  • และเมื่อคอนโซลเปิดเรียกมันว่าเป็นมากที่สุดเท่าที่ 100 000 ครั้งช้า

ไม่ใช่ว่าคุณจะสังเกตเห็นความล่าช้าของประสิทธิภาพหากคุณมีการconsole.…โทรจำนวนพอสมควรที่เริ่มทำงานหนึ่งครั้ง (หนึ่งร้อยจะใช้เวลา 2 มิลลิวินาทีในการติดตั้ง Chrome ของฉัน - หรือ 20 มิลลิวินาทีเมื่อคอนโซลเปิดอยู่) แต่ถ้าคุณบันทึกข้อมูลลงในคอนโซลซ้ำ ๆ เช่นการเชื่อมต่อผ่านrequestAnimationFrameมันอาจทำให้สิ่งต่างๆยุ่งเหยิงได้

อัปเดต:

ในการทดสอบนี้ฉันได้ตรวจสอบแนวคิดของ "บันทึกที่ซ่อนอยู่" ที่กำหนดเองสำหรับการใช้งานจริงซึ่งมีตัวแปรที่เก็บข้อความบันทึกพร้อมให้บริการตามต้องการ ปรากฎว่าเป็น

  • ประมาณ 1 000 ครั้งเร็วกว่าพื้นเมืองconsole.log,
  • และเห็นได้ชัดว่าเร็วกว่า 10,000 เท่าหากผู้ใช้เปิดคอนโซล

1
เมื่อคอมไพเลอร์เห็นฟังก์ชันว่างมันจะดำเนินการอะไรไม่ได้เนื่องจากเห็นบรรทัดที่จะเรียกใช้งานได้จะต้องเรียกใช้ฟังก์ชัน คอมไพเลอร์ไม่เรียกใช้ฟังก์ชันว่างเปล่าที่ไม่ได้ใช้เป็นการเพิ่มประสิทธิภาพ
SidOfc

1
@SidneyLiebrand ขอบคุณสำหรับข้อมูลที่ควรรู้ ผลของการทดสอบที่สองสามารถเพิ่มประสิทธิภาพในลักษณะเดียวกับที่console.logแม้ว่า ทั้งสองเป็นฟังก์ชันที่ก่อให้เกิดผลข้างเคียง
tomekwi

1
console.logโดยตัวมันเองไม่ได้ส่งผลกระทบต่อประสิทธิภาพอย่างแท้จริงในแบบที่คุณจะสังเกตเห็นได้เว้นแต่คุณจะผูกเข้ากับตัวจัดการการเลื่อน / ปรับขนาด สิ่งเหล่านี้เรียกว่ามากและหากเบราว์เซอร์ของคุณต้องส่งข้อความไปยังคอนโซลเช่น 30 / 60x ต่อวินาทีมันอาจน่าเกลียด แล้วก็มีข้อผิดพลาดของ IE ที่ไม่อนุญาตให้คุณconsole.logปิดคอนโซลเลย :(
SidOfc

1
คุณพูดถูก - ฉันเขียนไว้ในคำตอบของฉันด้วย ตามกฎทั่วไปฉันพยายามที่จะไม่มีการเรียกคอนโซลในรหัสการผลิต แต่ประสิทธิภาพไม่ใช่เหตุผล แต่เป็นเพราะ“ มันง่ายเกินไปสำหรับคนธรรมดาที่จะอ่านบันทึกของคุณ” ตามที่ @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


11

หากคุณสร้างทางลัดไปยังคอนโซลในสคริปต์หลักทั่วไปเช่น:

var con = console;

จากนั้นใช้ con.log ("ข้อความ") หรือ con.error ("ข้อความแสดงข้อผิดพลาด") ตลอดทั้งรหัสของคุณในการผลิตคุณสามารถ rewire con ในตำแหน่งหลักเพื่อ:

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

16
ทางที่สกปรก:console.log = function(){}
br4nnigan

10

การใช้คุณลักษณะการดีบัก console.log จะลดประสิทธิภาพการดำเนินการของ JavaScript หรือไม่ จะส่งผลต่อความเร็วของการเรียกใช้สคริปต์ในสภาพแวดล้อมการผลิตหรือไม่

แน่นอนว่าconsole.log()จะลดประสิทธิภาพของโปรแกรมของคุณเนื่องจากต้องใช้เวลาในการคำนวณ

มีวิธีปิดใช้งานบันทึกคอนโซลในสภาพแวดล้อมการใช้งานจริงจากตำแหน่งคอนฟิกูเรชันเดียวหรือไม่?

ใส่รหัสนี้ที่จุดเริ่มต้นของสคริปต์ของคุณเพื่อแทนที่ฟังก์ชัน console.log มาตรฐานเป็นฟังก์ชันว่าง

console.log = function () { };

2
นี่ดูเหมือนจะเป็นหนึ่งในโซลูชันที่ง่ายที่สุดสำหรับการปิดใช้งานบันทึกคอนโซลในสภาพแวดล้อมการใช้งานจริง สงสัยว่าทำไมไม่สนใจอีก! เราสามารถควบคุมนิยามของฟังก์ชันว่างนี้ได้ภายใต้ตัวแปรซึ่งเราสามารถสลับเป็นจริง / เท็จขึ้นอยู่กับสภาพแวดล้อมที่เรากำลังทำงานอยู่ (prod หรือ dev)
Anshuman Manral

2
นี่คือคำตอบที่ยอดเยี่ยม! ขอบคุณ!
Systems Rebooter

6

การเรียกใช้ฟังก์ชันใด ๆ จะทำให้ประสิทธิภาพลดลงเล็กน้อย แต่ไม่console.logควรมีผลกระทบใด ๆ

อย่างไรก็ตามมันจะทำให้เกิดข้อผิดพลาดที่ไม่ได้กำหนดในเบราว์เซอร์รุ่นเก่าที่ไม่รองรับ console


3

การตีประสิทธิภาพจะน้อยมากอย่างไรก็ตามในเบราว์เซอร์รุ่นเก่าจะทำให้เกิดข้อผิดพลาดของ JavaScript หากคอนโซลผู้ใช้เบราว์เซอร์ไม่ได้เปิดlog is not a function of undefinedอยู่ ซึ่งหมายความว่าโค้ด JavaScript ทั้งหมดหลังจากการเรียก console.log จะไม่ทำงาน

คุณสามารถสร้าง wrapper เพื่อตรวจสอบว่าwindow.consoleเป็นอ็อบเจ็กต์ที่ถูกต้องหรือไม่จากนั้นเรียก console.log ใน wrapper สิ่งง่ายๆเช่นนี้จะได้ผล:

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

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

นี่คือซอ: http://jsfiddle.net/enDDV/


2

ฉันทำการทดสอบ jsPerf นี้: http://jsperf.com/console-log1337

ดูเหมือนจะใช้เวลาไม่นานกว่าการเรียกฟังก์ชันอื่น ๆ

แล้วเบราว์เซอร์ที่ไม่มีคอนโซล API ล่ะ? หากคุณจำเป็นต้องใช้ console.log สำหรับการดีบักคุณอาจรวมสคริปต์ไว้ในการปรับใช้งานจริงของคุณเพื่อแทนที่คอนโซล API ดังที่ Paul แนะนำในคำตอบของเขา


ถ้าฉันสามารถเลือกคำตอบได้สองคำสิ่งนี้จะขึ้นไปข้างบน
Sudantha

1
การทดสอบของคุณไม่เพียงเพิ่มการเรียก console.log แต่ยังดำเนินการ jquery เดียวกันสองครั้ง ฉันได้สร้างการแก้ไขการทดสอบของคุณต่อไปนี้หวังว่าจะช่วยได้: jsperf.com/console-log1337/7 PS: ขอบคุณฉันไม่รู้เกี่ยวกับ jsperf.com :)
dubrox

2
ดูเหมือนว่าจะช้ากว่าการเรียกฟังก์ชันปกติมาก ในการดวลโดยตรงผลลัพธ์นั้นหาที่เปรียบไม่ได้: jsperf.com/console-log1337/14
tomekwi

1
คำตอบที่ไม่ดี ไม่ได้แก้ไขจากระยะไกล การคิดที่ต้องการโหวตเพิ่มขึ้นเนื่องจาก @tomekwi แสดงให้เห็นถึงความแตกต่างที่น่าทึ่ง ฉันได้ทำการทดสอบในโลกแห่งความเป็นจริงหลายครั้งแล้วและสามารถพูดได้โดยไม่ต้องสงสัยว่าคอนโซลสแปมจะทำให้เกิดการโจมตีด้านประสิทธิภาพอย่างแน่นอน บันทึกสองสามรายการที่นี่และทุก ๆ สองหรือสองวินาทีไม่ใช่เรื่องใหญ่ แต่บันทึกบางสิ่งบ่อยๆ (ในการอัปเดตเฟรมการแสดงผลส่วนประกอบขนาดใหญ่อีกครั้ง) และความแตกต่างที่มีและไม่มี console.log คือทั้งกลางวันและกลางคืน
Lev

1

ฉันทำวิธีนี้เพื่อรักษาลายเซ็นดั้งเดิมของวิธีคอนโซล ในตำแหน่งทั่วไปโหลดก่อน JS อื่น ๆ :

var DEBUG = false; // or true 

จากนั้นตลอดรหัส

if (DEBUG) console.log("message", obj, "etc");
if (DEBUG) console.warn("something is not right", obj, "etc");
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.