นี่คือ 10 กฎประสิทธิภาพที่เราปฏิบัติตามเมื่อใช้ node.js:
1. หลีกเลี่ยงการใช้รหัสแบบซิงโครนัส
ในแง่ของการออกแบบ node.js เป็นเธรดเดี่ยว ในการอนุญาตให้มีเธรดเดียวที่จะจัดการคำขอที่เกิดขึ้นพร้อมกันจำนวนมากคุณไม่สามารถปล่อยให้เธรดรอการปิดกั้นการทำงานแบบซิงโครนัสหรือการดำเนินการที่ยาวนาน คุณสมบัติที่โดดเด่นของ node.js คือมันได้รับการออกแบบและนำไปใช้จากบนลงล่างเพื่อให้ได้อะซิงโครนัส สิ่งนี้ทำให้เหมาะมากสำหรับโปรแกรมประเภทเหตุการณ์
น่าเสียดายที่ยังมีความเป็นไปได้ที่การโทรแบบซิงโครนัส/การบล็อกจะเกิดขึ้น ตัวอย่างเช่นการดำเนินการของระบบไฟล์จำนวนมากมีทั้งรุ่นซิงโครนัสและแบบอะซิงโครนัสเช่น WriteFile และ WriteFilesync แม้ว่าคุณจะใช้รหัสเพื่อควบคุมวิธีการซิงโครไนซ์ แต่ก็ยังสามารถใช้ไลบรารีฟังก์ชั่นภายนอกที่บล็อกการโทรโดยไม่ตั้งใจ เมื่อคุณทำสิ่งนี้ผลกระทบต่อประสิทธิภาพมีขนาดใหญ่มาก
// ดี: เขียนไฟล์ asynchronouslyfs.writefile ('message.txt', 'hello node', ฟังก์ชั่น (err) {console.log ("มันถูกบันทึกและเซิร์ฟเวอร์ยังคงตอบสนอง!");}); // bad: เขียนไฟล์ synchronouslyfs.writefilesync ('message.txt', 'hello node'); console.log ("บันทึก แต่คุณเพิ่งบล็อกคำขอทั้งหมด!");บันทึกการเริ่มต้นของเราโดยไม่ได้ตั้งใจรวมการเรียกแบบซิงโครนัสเพื่อเขียนเนื้อหาไปยังดิสก์เมื่อนำไปใช้ หากเราไม่ทำการทดสอบประสิทธิภาพมันจะง่ายที่จะเพิกเฉยต่อปัญหานี้ เมื่อใช้อินสแตนซ์ Node.js ในกล่องนักพัฒนาเป็นแบบทดสอบมาตรฐานการโทรแบบซิงโครนัสนี้จะทำให้ประสิทธิภาพลดลงจากคำขอนับพันต่อวินาทีถึงเพียงไม่กี่โหล
2. ปิดพูลซ็อกเก็ต
ไคลเอนต์ HTTP ของ node.js จะใช้ซ็อกเก็ตพูลโดยอัตโนมัติ: โดยค่าเริ่มต้นจะมีเพียง 5 ซ็อกเก็ตต่อโฮสต์ แม้ว่าการใช้ซ็อกเก็ตซ้ำอาจทำให้ทรัพยากรเพิ่มขึ้นภายใต้การควบคุมหากคุณต้องการจัดการกับคำขอที่เกิดขึ้นพร้อมกันจากโฮสต์เดียวกันมันจะนำไปสู่ชุดคอขวด ในกรณีนี้เป็นความคิดที่ดีที่จะเพิ่มมูลค่าของ maxsockets หรือปิดซ็อกเก็ตพูล:
// ปิดการใช้งานซ็อกเก็ตพล็อต var http = ต้องการ ('http'); ตัวเลือก var = {..... }; opotions.agent = false; var req = http.request (ตัวเลือก)3. อย่าปล่อยให้ทรัพยากรคงที่ใช้ node.js
สำหรับทรัพยากรคงที่เช่น CSS และรูปภาพให้ใช้เว็บเซิร์ฟเวอร์มาตรฐานแทน Node.Js ตัวอย่างเช่น LinkedIn Mobile ใช้ Nginx นอกจากนี้เรายังใช้เครือข่ายการส่งเนื้อหา (CDNs) ซึ่งสามารถคัดลอกทรัพยากรคงที่ทั่วโลกไปยังเซิร์ฟเวอร์ สิ่งนี้มีประโยชน์สองประการ: (1) สามารถลดการโหลดบนเซิร์ฟเวอร์ Node.js ของเรา (2) CDNs สามารถอนุญาตให้ส่งเนื้อหาแบบคงที่บนเซิร์ฟเวอร์ใกล้กับผู้ใช้มากขึ้นซึ่งจะช่วยลดเวลารอคอย
4. แสดงผลกับลูกค้า
ลองเปรียบเทียบความแตกต่างระหว่างการเรนเดอร์เซิร์ฟเวอร์และการเรนเดอร์ไคลเอนต์อย่างรวดเร็ว หากเราใช้ node.js เพื่อแสดงผลทางฝั่งเซิร์ฟเวอร์สำหรับแต่ละคำขอเราจะส่งหน้า HTML กลับมาดังต่อไปนี้:
<!-ตัวอย่างของหน้าเว็บง่าย ๆ แสดงผลด้านเซิร์ฟเวอร์ทั้งหมด-> <! doctype html> <html> <head> <title> LinkedIn Mobile </title> </head> <body> <div> <img src = "http://mobile-cdn.linkedin.com/images </div> </body> </html>
โปรดให้ความสนใจกับการสังเกตเนื้อหาทั้งหมดของหน้านี้ยกเว้นชื่อของผู้ใช้ส่วนที่เหลือจะคงที่: เนื้อหาที่ใช้งานมากเกินไปโดยผู้ใช้แต่ละคนและหน้านั้นเหมือนกัน ดังนั้นวิธีการที่มีประสิทธิภาพมากขึ้นคือการให้ node.js ส่งคืนเฉพาะเนื้อหาแบบไดนามิกที่กำหนดโดยหน้าในรูปแบบ JSON
{"ชื่อ": "John"}
ส่วนที่เหลือของหน้า - แท็ก HTML แบบคงที่ทั้งหมด - สามารถวางไว้ในเทมเพลต JavaScript (เช่น template underscore.js):
<!-ตัวอย่างของเทมเพลต JavaScript ที่สามารถแสดงผลด้านไคลเอ็นต์-> <! Doctype html> <html> <head> <title> LinkedIn Mobile </title> </head> <body> <div> <img src = "http://mobile-cdn.linkedin.com/images - </div> </body> </html>
การปรับปรุงประสิทธิภาพมาจากสถานที่เหล่านี้: ตามที่จุดที่สามบอกว่าเทมเพลต JavaScript แบบคงที่สามารถให้บริการบนฝั่งเซิร์ฟเวอร์ผ่าน WebServer (เช่น Nginx) หรือนำไปใช้กับ CDN ที่ดีกว่า นอกจากนี้เทมเพลต JavaScript สามารถแคชในเบราว์เซอร์หรือเก็บไว้ในพื้นที่ หลังจากโหลดหน้าเริ่มต้นทั้งหมดข้อมูลเดียวที่ต้องส่งไปยังลูกค้าคือ JSON ซึ่งจะมีประสิทธิภาพมากที่สุด วิธีนี้สามารถลดภาระของ CPU, IO และ Node.js ได้อย่างมาก
5. ใช้ gzip
เซิร์ฟเวอร์และลูกค้าจำนวนมากสนับสนุน GZIP เพื่อบีบอัดคำขอและคำตอบ ไม่ว่าคุณจะตอบไคลเอนต์หรือส่งคำขอไปยังเซิร์ฟเวอร์ระยะไกลตรวจสอบให้แน่ใจว่าได้ใช้ประโยชน์อย่างเต็มที่
6. การทำให้ขนานกัน
ลองปล่อยให้การดำเนินการบล็อกทั้งหมดของคุณ - ส่งคำขอการโทร DB และการเข้าถึงระบบไฟล์แบบขนานไปยังบริการระยะไกล สิ่งนี้จะช่วยลดเวลารอคอยสำหรับการปิดกั้นที่ช้าที่สุดแทนที่จะรอเวลารอคอยสำหรับการปิดกั้นทั้งหมด เพื่อให้การเรียกกลับและการจัดการข้อผิดพลาดสะอาดเราใช้ขั้นตอนในการควบคุมการรับส่งข้อมูล
7. การเปิดเสรี
LinkedIn Mobile ใช้เฟรมเวิร์กด่วนเพื่อจัดการรอบการร้องขอ/ตอบกลับ ตัวอย่างด่วนจำนวนมากรวมถึงการกำหนดค่าต่อไปนี้:
App.use (Express.session ({Secret: "คีย์บอร์ดแมว"}));
โดยค่าเริ่มต้นข้อมูลเซสชันจะถูกเก็บไว้ในหน่วยความจำซึ่งเพิ่มค่าใช้จ่ายจำนวนมากให้กับเซิร์ฟเวอร์โดยเฉพาะอย่างยิ่งเมื่อจำนวนผู้ใช้เพิ่มขึ้น คุณสามารถใช้ที่เก็บเซสชันภายนอกเช่น MongoDB หรือ Redis แต่คำขอแต่ละครั้งจะส่งผลให้ค่าใช้จ่ายของการโทรจากระยะไกลเพื่อรับข้อมูลเซสชัน เมื่อเป็นไปได้ตัวเลือกที่ดีที่สุดคือการจัดเก็บข้อมูลไร้สัญชาติทั้งหมดทางฝั่งเซิร์ฟเวอร์ โดยการเปิดเสรีเซสชันโดยไม่รวมการกำหนดค่าด่วนด้านบนคุณจะเห็นประสิทธิภาพที่ดีขึ้น
8. ใช้โมดูลไบนารี
หากเป็นไปได้ให้แทนที่โมดูล JavaScript ด้วยโมดูลไบนารี ตัวอย่างเช่นเมื่อเราแปลงจากโมดูล SHA ที่เขียนใน JavaScript เป็นเวอร์ชันที่รวบรวมของ Node.js เราจะเห็นการก้าวกระโดดครั้งใหญ่ไปข้างหน้าในการแสดง:
// ใช้ในตัวหรือไบนารีโมดูล crypto = ต้องการ ('crypto'); var hash = crypto.createhmac ("sha1", key) .update (signaturebase) .digest ("base64");9. แทนที่ไลบรารีไคลเอ็นต์ด้วยมาตรฐาน V8 JavaScript
ไลบรารี JavaScript จำนวนมากถูกสร้างขึ้นเพื่อใช้บนเว็บเบราว์เซอร์เพราะในสภาพแวดล้อม JavaScript ตัวอย่างเช่นเบราว์เซอร์บางตัวรองรับฟังก์ชั่นเช่น foreach, MAP และลด แต่เบราว์เซอร์บางส่วนไม่ได้ ดังนั้นไลบรารีลูกค้ามักจะใช้รหัสที่ไม่มีประสิทธิภาพจำนวนมากเพื่อเอาชนะความแตกต่างของเบราว์เซอร์ ในทางกลับกันใน node.js คุณสามารถรู้ได้อย่างชัดเจนว่าวิธี JavaScript ใดมีผลบังคับใช้: V8 JavaScript Engine รองรับ Node.js ในการใช้งาน ecmascript ที่ระบุในรุ่นที่ห้าของ ECMA-262 แทนที่ไลบรารีไคลเอนต์โดยตรงด้วยฟังก์ชั่น V8 JavaScript มาตรฐานคุณจะพบการปรับปรุงประสิทธิภาพที่สำคัญ
10. รักษารหัสของคุณให้เล็กและเบา
การใช้อุปกรณ์มือถือจะทำให้การเข้าถึงช้าและเวลาแฝงสูงซึ่งบอกให้เราเก็บรหัสของเราให้เล็กและเบา ปรัชญาเดียวกันนี้ได้รับการบำรุงรักษาสำหรับรหัสเซิร์ฟเวอร์ บางครั้งมองย้อนกลับไปที่การตัดสินใจของคุณและถามคำถามตัวเองเช่น: "เราต้องการโมดูลนี้จริง ๆ หรือไม่", "ทำไมเราถึงใช้เฟรมเวิร์กนี้? รหัสขนาดเล็กและแสงมักจะมีประสิทธิภาพและรวดเร็วมากขึ้น
ลองดู
เราทำงานอย่างหนักเพื่อให้แอพมือถือของเราเร็ว ลองใช้บนแพลตฟอร์มเช่นแอพ iPhone แอพ Android และรุ่นมือถือ HTML5 เพื่อแจ้งให้เราทราบว่าเรากำลังทำอะไรอยู่