Node.js ได้รับประโยชน์จากคุณสมบัติที่ขับเคลื่อนด้วยเหตุการณ์และแบบอะซิงโครนัสและเร็ว ๆ นี้ อย่างไรก็ตามมันเป็นไปไม่ได้ที่จะรวดเร็วในเครือข่ายที่ทันสมัย หากคุณวางแผนที่จะใช้ node.js เพื่อพัฒนาแอปพลิเคชันเว็บถัดไปของคุณคุณควรทำทุกอย่างเพื่อให้แอปพลิเคชันของคุณเร็วขึ้นและรวดเร็วเป็นพิเศษ บทความนี้จะแนะนำ 10 รายการและหลังจากการทดสอบแล้วมันสามารถปรับปรุงทักษะของแอปพลิเคชันโหนดได้อย่างมาก โดยไม่ต้องกังวลใจเพิ่มเติมลองมาดูทีละคน
1. ขนาน
เมื่อสร้างเว็บแอปพลิเคชันคุณอาจต้องโทรหา API ภายในหลายครั้งเพื่อรับข้อมูลต่าง ๆ ตัวอย่างเช่นสมมติว่าในหน้าแดชบอร์ดคุณต้องเรียกใช้สายต่อไปนี้:
ข้อมูลผู้ใช้ - GetUserProfile ()
กิจกรรมปัจจุบัน - getRecentActivity ()
สมัครสมาชิกเนื้อหา - getSubscriptions ()
เนื้อหาการแจ้งเตือน - GetNotifications ()
ในการรับข้อมูลนี้คุณควรสร้างมิดเดิลแวร์แยกต่างหากสำหรับแต่ละวิธีจากนั้นเชื่อมโยงไปยังเส้นทางแดชบอร์ด แต่ปัญหาคือการดำเนินการของวิธีการเหล่านี้เป็นเส้นตรงและวิธีต่อไปจะไม่เริ่มจนกว่าจะเสร็จสิ้นก่อนหน้านี้ ทางออกที่เป็นไปได้คือเรียกพวกเขาในแบบขนาน
อย่างที่คุณทราบ Node.js นั้นดีมากในการเรียกใช้หลายวิธีในแบบคู่ขนานเนื่องจากความไม่แน่นอน เราไม่สามารถเสียทรัพยากรธรรมชาติ วิธีการที่ฉันกล่าวถึงข้างต้นไม่มีการพึ่งพาดังนั้นเราจึงสามารถดำเนินการได้ในแบบคู่ขนาน ด้วยวิธีนี้เราสามารถลดจำนวนมิดเดิลแวร์และเพิ่มความเร็วอย่างมาก
เราสามารถใช้ async.js เพื่อจัดการกับการขนานซึ่งเป็นโมดูลโหนดที่ใช้เป็นพิเศษในการฝึกอบรม JavaScript แบบอะซิงโครนัส รหัสต่อไปนี้แสดงให้เห็นถึงวิธีการใช้ async.js เพื่อเรียกใช้หลายวิธีแบบขนาน:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น runinparallel () {
async.parallel ([
GetUserProfile
GetRecentActivity
GetSubscriptions
GetNotifications
], ฟังก์ชั่น (เอ่อ, ผลลัพธ์) {
// การโทรกลับนี้จะทำงานเมื่อฟังก์ชั่นทั้งหมดเสร็จสิ้น
-
-
หากคุณต้องการดูเชิงลึกมากขึ้น async.js โปรดย้ายไปที่หน้า GitHub
2. อะซิงโครนัส
โดยการออกแบบ node.js เป็นเกลียวเดี่ยว ขึ้นอยู่กับสิ่งนี้รหัสซิงโครนัสจะบล็อกแอปพลิเคชันทั้งหมด ตัวอย่างเช่น API ระบบไฟล์ส่วนใหญ่มีเวอร์ชันที่ซิงโครไนซ์ รหัสต่อไปนี้แสดงให้เห็นถึงการดำเนินการสองรายการ: การอ่านไฟล์แบบซิงโครนัสและอะซิงโครนัส:
การคัดลอกรหัสมีดังนี้:
// asynchronous
fs.readfile ('file.txt', ฟังก์ชัน (err, buffer) {
var content = buffer.toString ();
-
// ซิงโครนัส
var content = fs.readfilesync ('file.txt'). toString ();
อย่างไรก็ตามหากคุณทำการบล็อกการปิดกั้นระยะยาวเธรดหลักจะถูกบล็อกจนกว่าการดำเนินการเหล่านี้จะเสร็จสมบูรณ์ สิ่งนี้จะช่วยลดประสิทธิภาพของแอปพลิเคชันของคุณได้อย่างมาก ดังนั้นจึงเป็นการดีที่สุดที่จะตรวจสอบให้แน่ใจว่ารหัสของคุณใช้ API เวอร์ชันอะซิงโครนัสอย่างน้อยคุณควรเป็นแบบอะซิงโครนัสในโหนดประสิทธิภาพ ยิ่งกว่านั้นคุณควรระมัดระวังอย่างมากเมื่อเลือกโมดูลบุคคลที่สาม เพราะเมื่อคุณพยายามลบการดำเนินการซิงโครไนซ์ออกจากรหัสของคุณการโทรแบบซิงโครนัสจากไลบรารีภายนอกจะเสียความพยายามทั้งหมดและลดประสิทธิภาพแอปพลิเคชันของคุณ
3. แคช
หากคุณใช้ข้อมูลบางอย่างที่ไม่เปลี่ยนแปลงบ่อยครั้งคุณควรแคชเพื่อปรับปรุงประสิทธิภาพ ตัวอย่างเช่นรหัสต่อไปนี้เป็นตัวอย่างของการรับโพสต์ล่าสุดและแสดง:
การคัดลอกรหัสมีดังนี้:
var router = express.router ();
router.route ('/lastposts') รับ (ฟังก์ชั่น (req, res) {
post.getLatest (ฟังก์ชั่น (เอ่อโพสต์) {
ถ้า (err) {
โยนเอ่อ;
-
res.render ('โพสต์', {โพสต์: โพสต์});
-
-
หากคุณไม่โพสต์บ่อยคุณสามารถแคชรายการโพสต์และทำความสะอาดได้หลังจากผ่านไประยะหนึ่ง ตัวอย่างเช่นเราสามารถใช้โมดูล Redis เพื่อให้บรรลุเป้าหมายนี้ แน่นอนคุณต้องติดตั้ง Redis บนเซิร์ฟเวอร์ของคุณ จากนั้นคุณสามารถบันทึกคู่คีย์/ค่าด้วยไคลเอนต์ที่เรียกว่า node_redis ตัวอย่างต่อไปนี้แสดงวิธีการโพสต์แคช:
การคัดลอกรหัสมีดังนี้:
var redis = ต้องการ ('redis')
client = redis.createClient (null, null, {detect_buffers: true}),
เราเตอร์ = Express.router ();
router.route ('/lastposts') รับ (ฟังก์ชั่น (req, res) {
client.get ('โพสต์', ฟังก์ชั่น (err, โพสต์) {
ถ้า (โพสต์) {
return res.render ('โพสต์', {โพสต์: json.parse (โพสต์)});
-
post.getLatest (ฟังก์ชั่น (เอ่อโพสต์) {
ถ้า (err) {
โยนเอ่อ;
-
client.set ('โพสต์', json.stringify (โพสต์));
res.render ('โพสต์', {โพสต์: โพสต์});
-
-
-
ดูสิให้ตรวจสอบแคช Redis ก่อนเพื่อดูว่ามีโพสต์ใด ๆ ถ้าเป็นเช่นนั้นเราจะใช้รายการโพสต์เหล่านี้จากแคช มิฉะนั้นเราจะดึงเนื้อหาฐานข้อมูลและแคชผลลัพธ์ นอกจากนี้หลังจากระยะเวลาหนึ่งเราสามารถทำความสะอาดแคช Redis เพื่อให้เนื้อหาสามารถอัปเดตได้
4. การบีบอัด GZIP
การเปิดการบีบอัด GZIP จะส่งผลกระทบอย่างมากต่อเว็บแอปพลิเคชันของคุณ เมื่อเบราว์เซอร์บีบอัด GZIP ร้องขอทรัพยากรบางอย่างเซิร์ฟเวอร์จะบีบอัดก่อนที่การตอบกลับจะถูกส่งกลับไปยังเบราว์เซอร์ หากคุณไม่ได้ใช้ GZIP เพื่อบีบอัดทรัพยากรคงที่ของคุณอาจใช้เวลานานกว่าที่เบราว์เซอร์จะได้รับ
ในแอพพลิเคชั่นด่วนเราสามารถใช้มิดเดิลแวร์ Express-intatic.static () ในตัวเพื่อจัดการเนื้อหาคงที่ นอกจากนี้เนื้อหาคงที่สามารถบีบอัดและประมวลผลได้โดยใช้มิดเดิลแวร์บีบอัด นี่คือตัวอย่างการใช้งาน:
การคัดลอกรหัสมีดังนี้:
การบีบอัด var = ต้องการ ('การบีบอัด');
app.use (การบีบอัด ()); // ใช้การบีบอัด
app.use (express.static (path.join (__ dirname, 'สาธารณะ')));
5. ถ้าเป็นไปได้ให้กับลูกค้า
ขณะนี้มีเฟรมเวิร์ก MVC/MVVM ที่หลากหลายและทรงพลังเช่น AngularJs, Ember, Meteor ฯลฯ และเป็นเรื่องง่ายมากที่จะสร้างแอปพลิเคชันหน้าเดียว โดยทั่วไปคุณเพียงแค่ต้องเปิดเผย API และส่งคืนการตอบกลับ JSON ไปยังไคลเอนต์โดยไม่ต้องแสดงหน้าบนเซิร์ฟเวอร์ บนลูกค้าคุณสามารถจัดระเบียบ JSON ด้วยเฟรมเวิร์กและแสดงบน UI เฉพาะการส่งการตอบกลับ JSON บนเซิร์ฟเวอร์เท่านั้นที่สามารถบันทึกแบนด์วิดท์และปรับปรุงประสิทธิภาพได้เนื่องจากคุณไม่จำเป็นต้องส่งคืนเครื่องหมายเลย์เอาต์ในการตอบกลับแต่ละครั้งใช่คุณเพียงแค่ต้องคืน JSON บริสุทธิ์แล้วแสดงผลบนไคลเอนต์
ลองมาดูการสอนของฉันซึ่งเกี่ยวกับวิธีการเปิดเผย API ที่พักผ่อนโดยใช้ Express 4 ฉันยังเขียนบทช่วยสอนอีกครั้งที่แสดงวิธีการรวม API เหล่านี้เข้ากับ AngularJs
6. อย่าเก็บข้อมูลมากเกินไปในเซสชัน
สำหรับแอปพลิเคชันหน้าด่วนทั่วไปข้อมูลเซสชันจะถูกบันทึกไว้ในหน่วยความจำโดยค่าเริ่มต้น เมื่อคุณบันทึกข้อมูลมากเกินไปในเซสชันมันจะเพิ่มค่าใช้จ่ายเซิร์ฟเวอร์อย่างมีนัยสำคัญ ดังนั้นไม่ว่าคุณจะเปลี่ยนไปใช้วิธีการจัดเก็บข้อมูลอื่นเพื่อบันทึกข้อมูลเซสชันหรือพยายามลดจำนวนข้อมูลที่เก็บไว้ในเซสชันให้น้อยที่สุด
ตัวอย่างเช่นเมื่อผู้ใช้เข้าสู่แอพของคุณคุณสามารถบันทึก ID ของพวกเขาได้เฉพาะในเซสชันแทนที่จะเป็นวัตถุข้อมูลผู้ใช้ทั้งหมด นอกจากนี้สำหรับคำถามเหล่านั้นที่คุณสามารถรับวัตถุจาก ID คุณควรใช้ MongoDB หรือ REDIS เพื่อจัดเก็บข้อมูลเซสชัน
7. เพิ่มประสิทธิภาพการสอบถาม
สมมติว่าคุณมีบล็อกและคุณต้องการแสดงโพสต์ล่าสุดในหน้าแรกของคุณ คุณอาจได้รับข้อมูลผ่านพังพอนเช่นนี้:
การคัดลอกรหัสมีดังนี้:
post.find (). ขีด จำกัด (10) .Exec (ฟังก์ชั่น (เอ่อ, โพสต์) {
// ส่งโพสต์ไปยังลูกค้า
-
อย่างไรก็ตามปัญหาคือวิธีการค้นหาของ Mongoose () จะสอบถามฟิลด์ทั้งหมดของวัตถุและไม่จำเป็นต้องใช้ฟิลด์จำนวนมากในหน้าแรก ตัวอย่างเช่นความคิดเห็นบันทึกการตอบกลับไปยังโพสต์เฉพาะ เราไม่จำเป็นต้องแสดงการตอบกลับบทความดังนั้นเราจึงสามารถลบออกได้เมื่อสอบถาม สิ่งนี้จะเพิ่มความเร็วอย่างไม่ต้องสงสัย แบบสอบถามข้างต้นสามารถปรับให้เหมาะสมเช่นนี้:
การคัดลอกรหัสมีดังนี้:
post.find (). ขีด จำกัด (10). exclude ('ความคิดเห็น'). exec (ฟังก์ชั่น (err, โพสต์) {
// ส่งโพสต์ไปยังลูกค้า
-
8. ใช้วิธี V8 มาตรฐาน
การดำเนินการบางอย่างในคอลเลกชันเช่นแผนที่ลดและ foreach ไม่จำเป็นต้องรองรับเบราว์เซอร์ทั้งหมด เราสามารถแก้ปัญหาความเข้ากันได้ของเบราว์เซอร์ผ่านห้องสมุดเบื้องหน้า แต่สำหรับ node.js คุณต้องรู้ว่าการดำเนินการใดที่เอ็นจิ้น V8 JavaScript ของ Google รองรับ ด้วยวิธีนี้คุณสามารถใช้วิธีการในตัวเหล่านี้โดยตรงเพื่อใช้งานคอลเลกชันทางฝั่งเซิร์ฟเวอร์
9. ใช้ nginx ที่ด้านหน้าของโหนด
Nginx เป็นเว็บเซิร์ฟเวอร์ขนาดเล็กและมีน้ำหนักเบาที่สามารถลดการโหลดบนเซิร์ฟเวอร์ Node.js ของคุณ คุณสามารถกำหนดค่าทรัพยากรคงที่บน Nginx แทนบนโหนด คุณสามารถบีบอัดการตอบกลับด้วย GZIP บน Nginx เพื่อให้การตอบสนองทั้งหมดมีขนาดเล็กลง ดังนั้นหากคุณมีผลิตภัณฑ์ที่ใช้งานได้ฉันคิดว่าคุณควรใช้ Nginx เพื่อปรับปรุงความเร็วในการทำงาน
10. บรรจุภัณฑ์ JavaScript
ในที่สุดคุณยังสามารถปรับปรุงความเร็วของแอปพลิเคชันหน้าได้อย่างมากโดยบรรจุไฟล์ JS หลายไฟล์ เมื่อเบราว์เซอร์พบองค์ประกอบ <script> ในการเรนเดอร์หน้าจะถูกบล็อกและจะไม่ทำงานต่อไปจนกว่าจะได้รับสคริปต์ (เว้นแต่จะตั้งค่าคุณสมบัติแบบอะซิงโครนัส) ตัวอย่างเช่นหากหน้าของคุณมีไฟล์ JavaScript ห้าไฟล์เบราว์เซอร์จะออกคำขอ HTTP ห้ารายการแยกต่างหากเพื่อรับไฟล์เหล่านั้น หากไฟล์ห้าไฟล์เหล่านี้ถูกบีบอัดและบรรจุเป็นหนึ่งเดียวประสิทธิภาพโดยรวมจะได้รับการปรับปรุงอย่างมาก เช่นเดียวกันสำหรับไฟล์ CSS คุณสามารถใช้เครื่องมือรวบรวมเช่น Grunt/Gulp เพื่อจัดทำแพ็คเกจไฟล์ทรัพยากรของคุณ
สรุปแล้ว
เคล็ดลับ 10 ข้อข้างต้นสามารถปรับปรุงความเร็วของเว็บแอปพลิเคชันของคุณได้อย่างแน่นอน อย่างไรก็ตามฉันรู้ว่ามีที่ว่างสำหรับการปรับปรุงและเพิ่มประสิทธิภาพ หากคุณมีเคล็ดลับในการปรับปรุงประสิทธิภาพโปรดแจ้งให้เราทราบในการตอบกลับ
ขอบคุณสำหรับการอ่าน!