ข้อผิดพลาด Javascript ทั่วไปที่ส่งผลกระทบต่อประสิทธิภาพอย่างรุนแรงหรือไม่ [ปิด]


10

ที่ UI ล่าสุด / UX MeetUp ที่ฉันเข้าร่วมฉันให้ข้อเสนอแนะบางอย่างเกี่ยวกับเว็บไซต์ที่ใช้ Javascript (jQuery) สำหรับการโต้ตอบและ UI - มันเป็นภาพเคลื่อนไหวและการจัดการที่ค่อนข้างง่าย แต่ประสิทธิภาพของคอมพิวเตอร์ที่ยอดเยี่ยมน่ากลัว

จริงๆแล้วมันทำให้ฉันนึกถึงเว็บไซต์ / โปรแกรมมากมายที่ฉันเคยเห็นในประเด็นเดียวกันซึ่งการกระทำบางอย่างทำให้ประสิทธิภาพลดลง โดยส่วนใหญ่จะอยู่ใน (หรืออย่างน้อยก็สังเกตเห็นได้ชัดเจน) ในสถานการณ์ที่ Javascript เกือบจะทำหน้าที่เป็น Flash แทน นี่คือความแตกต่างอย่างสิ้นเชิงกับบางส่วนของ webapps ที่ฉันเคยใช้ที่มีจาวาสคริปต์และฟังก์ชั่นเพิ่มเติม แต่ทำงานได้อย่างราบรื่นมาก (COGNOS โดย IBM เป็นสิ่งหนึ่งที่ฉันคิดได้จากส่วนหัว)

ฉันชอบที่จะรู้ปัญหาทั่วไปบางอย่างที่ไม่ได้รับการพิจารณาเมื่อพัฒนา JS ที่จะฆ่าประสิทธิภาพของไซต์


มีแนวโน้มเหมือนกันกับโปรแกรมอื่นทุกโปรแกรม: ทำงานมากกว่าที่จำเป็นและทำงานเดียวกันซ้ำแล้วซ้ำอีกบ่อยครั้งหลายร้อยครั้ง

1
@delnan ที่เป็นจริงมาก แต่ดูเหมือนว่ามันจะแพร่หลายมากขึ้นใน JS การรับรู้อาจจะ?
Nic

1
การพูดถึง 'เว็บไซต์' เป็นเรื่องที่ค่อนข้างจะลำบากเมื่อพูดถึง JavaScript มันมีอยู่ทุกหนทุกแห่งและถูกใช้สำหรับทุก ๆ วัน
Adam Crossland

@ Adam Crossland คุณพูดถูก - ในกรณีเดียวกันฉันคิดว่าฉันช่วยนักพัฒนาด้วยแอพที่เป็นเจ้าของภาษาที่พึ่งพา jQuery เป็นอย่างมาก
Nic

1
ไม่ใช่คำตอบที่ตรงกับคำถามของคุณดังนั้นฉันจึงแสดงความคิดเห็น: ฉันเคยประสบกับสถานการณ์ที่ JavaScript ทำการเรนเดอร์จำนวนมากและจริงๆแล้วมันเป็นเอ็นจิ้นการเรนเดอร์ของเบราว์เซอร์ที่ใช้เวลาไม่กี่วินาที ดังนั้นเพื่อจัดการกับคอขวดของประสิทธิภาพฉันจะมองหาการแสดงผลที่ไม่จำเป็นก่อน
281377

คำตอบ:


8

ตัวจัดการประสิทธิภาพทั่วไปกำลังเรียก.lengthใช้ HTMLCollection ภายในforลูป:

function foo(collection) {
    for (var index = 0; index < collection.length; index++) {
        // do something awesome here
    }
}

รูปแบบการต่อต้านนั้นทำให้ขนาดของคอลเลกชันถูกคำนวณในแต่ละรอบผ่านลูป วิธีที่ดีกว่าคือการคำนวณความยาวนอกลูป:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}

3
ขึ้นอยู่กับเบราว์เซอร์ ใช้เกณฑ์มาตรฐานนี้เป็นตัวอย่าง: ใน FF 5 หนึ่ง "ปกติ" จะทำงานในเวลาเดียวกันกับเวอร์ชัน "ปรับให้เหมาะสม" และแม้แต่ในเบราว์เซอร์ที่เก่าและเบาบางจริงๆสิ่งที่เป็นไปได้นี้จะไม่เป็นคอขวดถ้า JS ทำสิ่งใดที่น่าสนใจกับองค์ประกอบ

1
อืม! บางทีคอมไพเลอร์ของ JIT ที่ได้รับการปรับให้เหมาะสมที่สุดในวันนี้กำลังทำให้ปัญญาแบบนี้ล้าสมัยไปแล้ว
Adam Crossland

4
ฉันไม่ใช่ผู้เชี่ยวชาญตัวจริงที่นี่ แต่จากสเป็ค ECMA ดูเหมือนว่าความยาวเป็นเพียงสมบัติของอาร์เรย์วัตถุ ดังนั้นการเรียกมันก็แค่คืนค่าแทนที่จะนับองค์ประกอบทั้งหมด ไม่ทราบว่าการใช้งานทั้งหมดเป็นไปตามข้อกำหนด แต่ถ้าเป็นเช่นนั้นรหัสของคุณจะไม่ปรับปรุงประสิทธิภาพเลย
Jacek Prucia

4
@JacekPrucia เขากล่าวว่าคอลเลกชันไม่อาร์เรย์ - ปกติในรหัสจริงนี้จะหมายถึงรายชื่อขององค์ประกอบ DOM document.getElementsByTagNameกลับโดยฟังก์ชั่นเช่น ฟังก์ชั่นคืนค่าสดnodeListซึ่งคำนวณความยาวของมันใหม่ทุกครั้งที่.lengthเข้าถึงคุณสมบัติ
Yi Jiang

2
@ JacekPrucia เป็นมาตรฐานการปรับปรุงประสิทธิภาพ การค้นหาอสังหาริมทรัพย์ไม่ถูก
Raynos

4

ไม่ปัญหาไม่ได้มาจาก JS ที่ใช้แทนแฟลช หากคุณไม่มั่นใจกับเอกสารเหล่านั้นเกี่ยวกับ actionscript: มันใกล้กับ JS มาก

ในฐานะนักฆ่าการแสดงคุณสามารถค้นหาแนวทางปฏิบัติที่ไม่ดีหลายประการ:

  • แนบตัวจัดการเหตุการณ์กับเหตุการณ์ต่อเนื่องเช่นการเลื่อนเมาส์หรือสิ่งที่คล้ายกัน สิ่งนี้มีข้อเสียเปรียบ 2 ประการ: หากเหตุการณ์ไม่ได้รับการเรียกใช้มากพอแอปพลิเคชันของคุณจะไม่ตอบสนอง ถ้ามันถูกเรียกมากเกินไปคุณจะมีโหลดซีพียูจำนวนมากเพื่ออะไร
  • การโทร AJAX แบบซิงโครนัส Javascript ไม่ได้มีหลายเธรดดังนั้นเมื่อส่วนหนึ่งของ JS กำลังรอบางสิ่งบางอย่างแอปพลิเคชันของคุณจะถูกตรึง คุณควรใช้การโทร AJAX แบบอะซิงโครนัสดีกว่าและใช้วิธีเดียวกันกับ setTimeout / setInterval เพื่อแยกเฟสการคำนวณที่ยาวและทำให้แอปพลิเคชันของคุณทำงานได้
  • ความซับซ้อนของอัลกอริทึมสูงเช่นในภาษาอื่น ๆ

ผมเคยเห็นมากกว่าปพลิเคชันไม่กี่พยายามที่จะหมุนอย่างง่ายดายหรือภาพเคลื่อนไหวภาพเต็มเบราว์เซอร์และล้มเหลวอย่างน่าสังเวชในกระบวนการ - นั่นคือสิ่งที่แสดงความคิดเห็นทดแทนแฟลชเกิดจาก :)
Nic

เนื่องจาก A แรกใน AJAX หมายถึงแบบอะซิงโครนัสเทคนิคไม่ใช่ AJAX ถ้ามันเป็นแบบซิงโครนัส แต่ประเด็นของคุณก็ยังดีอยู่
Karl Bielefeldt

ใช่ใช่ไม่ใช่ AJAX อย่างเคร่งครัด แต่อย่างไรก็ตามต้องหลีกเลี่ยงสิ่งนี้: D
deadalnix

3

ฉันให้ข้อเสนอแนะบางอย่างเกี่ยวกับเว็บไซต์ที่ใช้ Javascript (jQuery) สำหรับการโต้ตอบและ UI - มันเป็นภาพเคลื่อนไหวและการจัดการที่ค่อนข้างง่าย แต่ประสิทธิภาพของคอมพิวเตอร์ที่ดีนั้นยอดเยี่ยมมาก

ปัญหาที่ใหญ่ที่สุดปัญหาหนึ่งที่มีประสิทธิภาพคือการใช้ abstractions ระดับสูง (เช่น jQuery) โดยไม่เข้าใจโมเดล DOM พื้นฐานและโมเดลแอนิเมชั่น CSS3 (หรือแคนวาสหรือ svg)

หากคุณไม่ทราบวิธีการทำโดยปราศจาก abstractions แล้วคุณมีความรู้เป็นศูนย์แน่นอนของเทคนิคใดจะเร็วหรือช้า

เรียนรู้ JavaScript, เรียนรู้ DOM เมื่อคุณรู้จักสองคนนี้และคุณรู้ว่า abstractions ของคุณทำอะไรอยู่ภายใต้ประทุนคุณก็สามารถใช้มันได้อย่างมีประสิทธิภาพ แน่นอนว่าเวลาส่วนใหญ่ที่คุณรู้ว่าการทำ abstraction นั้นทำได้ช้าและทำเองโดยไม่ต้องมีไลบรารี่


1

ความงามและข้อเสียเปรียบของ Javascript คือมีความยืดหยุ่นอย่างยิ่ง อย่างที่บอกไปแล้วว่ามันช่วยให้คุณทำสิ่งที่คุณไม่ควรทำในหลายกรณี

จากการตรวจสอบรหัสที่ฉันได้เป็นส่วนหนึ่งของข้อกังวลที่สำคัญมักจะเกี่ยวข้องกับการแสดงผล CSS สำหรับนักพัฒนา JS รุ่นใหม่เรามักจะเห็นว่ามีการใช้ตัวแปรมากเกินไปในขอบเขตทั่วโลก

นอกจากนี้การปิดที่ไม่เหมาะสมมักทำให้หน่วยความจำรั่ว อย่างไรก็ตามเฟรมเวิร์ก Javascript ที่ทันสมัยส่วนใหญ่จะป้องกันปัญหาเหล่านี้ตราบใดที่โค้ดของคุณตามหลังเฟรมเวิร์ก


0

นี่คือลิงค์ด่วนที่ฉันพบเมื่อประมาณหนึ่งปีที่แล้วเกี่ยวกับการเขียนโค้ด jquery ที่ดีกว่า: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance /

สิ่งหนึ่งที่ฉันเพิ่งพบในรหัสเพื่อนร่วมงานที่ฆ่าประสิทธิภาพคือการแคชข้อมูลที่ไม่จำเป็นต้องใช้แคช

ตัวอย่าง:

var table = $("#data").dataTable(.....);

DataTablesเป็นปลั๊กอิน jQuery ที่เราใช้ในการทำกริดที่ดี อย่างไรก็ตามตารางมีแถวเกือบ 5k อยู่โดยใช้ปลั๊กอิน DataTables จากนั้นบันทึกไว้ในตัวแปรตารางทำให้ทั้ง FireFox และ IE เตือนว่าสคริปต์ใช้เวลานานเกินไป คุณธรรมของเรื่องราวแคชข้อมูลเท่านั้นหากคุณต้องการ


1
เสียงเหมือน DataTables เป็นปลั๊กอินที่ไม่มีประสิทธิภาพจริงๆหรือค่อนข้างแย่ แต่ก็มีปัญหากับการแคช 5k ไม่มีอะไร
Raynos

@ Raynos: เขาพูด 5k แถวไม่ใช่ 5 กิโลกรัมของข้อมูล "แถว" อาจเป็นเรื่องใหญ่มาก
Chris Farmer

@ChrisFarmer หาก "แถว" เป็นสิ่งที่มีขนาดใหญ่มากแสดงว่าคุณมีปัญหาแตกต่างกัน
Raynos

-1

จากสิ่งที่ผมเคยได้ยินforลูปเป็นคอมพิวเตอร์ที่เร็วกว่าของ $.each()jQuery


3
นี่เป็นคำตอบตลกหรือไม่
Raynos
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.