Back to notes
mastery-backend-express
Featured

Node.js Performance Mastery: เจาะลึก Memory Leak และ Event Loop

ทำไม Server แรมหมด? Event Loop Lag คืออะไร? เรียนรู้วิธีใช้เครื่องมือระดับ Senior เพื่อ Profile และแก้ปัญหาคอขวดใน Node.js

January 30, 20262 min read readNNexis by Seereen

🛑 1. The Problem First: "Server ตายเงียบ" (Memory Leak & CPU Spike)

ลองนึกถึงแอปที่รันไปสักพักแล้วจู่ๆ ก็ดับ (Crash) หรืออืดจน User เข้าไม่ได้:

HLJS JAVASCRIPT
// ❌ Naive Approach: เก็บข้อมูล User ในตัวแปร Global โดยไม่มีวันลบ
const activeUsers = []; // 🌋 ระเบิดเวลา! ทุกคนที่เข้ามาจะถูกเก็บไว้ที่นี่ตลอดกาล
app.get("/login", (req, res) => {
  activeUsers.push(req.user); // แรมจะเพิ่มขึ้นเรื่อยๆ จนเต็ม (Memory Leak)
  res.send("Logged in");
});

ปัญหา: Node.js ทำงานบน Single Thread ถ้าคุณทำเรื่องที่กิน CPU หนักๆ (Sync tasks) หรือทำตัวแปรค้างไว้ใน RAM ระบบจะ "หยุดหายใจ" ทันที (Event Loop Lag) และ Request อื่นๆ ทั้งโลกรวมถึงการเช็ค Health Check จะค้างตามไปด้วย นี่คือเหตุผลที่ Senior ต้องรู้ว่า "ข้างในเครื่องยนต์กำลังทำอะไรอยู่" ครับ


💡 2. Real-Life Analogy: ร้านอาหารที่มีเชฟคนเดียว (Single Thread)

  • Event Loop: เหมือน "เชฟที่ทำงานเร็วมาก". เขาทำหน้าที่แค่หยิบงานใส่เตา (Delegate) แล้วไปทำอย่างอื่นต่อ ถ้างานไหนใช้เวลา (ยิง API/DB) เขาจะไม่ยืนรอ
  • CPU Block (Sync Task): เหมือนการสั่งเชฟว่า "จงนั่งปอกกระเทียม 1 ล้านลูกให้เสร็จก่อนค่อยทำอย่างอื่น". เชฟจะขยับไปไหนไม่ได้เลย ลูกค้าโต๊ะอื่นจะไม่ได้กินข้าวแม้จะสั่งแค่ไข่ดาว (Event Loop Lag)
  • Memory Leak: เหมือนการสะสม "จานสกปรกไว้เต็มโต๊ะ" แล้วไม่เคยเอาไปล้าง. พื้นที่ในครัวจะน้อยลงเรื่อยๆ จนสุดท้ายเชฟไม่มีที่ขยับตัวและต้องปิดร้าน (Crash)

🚀 3. Execution Journey: ภารกิจตามล่ารูรั่ว (Profiling)

เมื่อ Server เริ่มอืด Senior จะไม่เดาสุ่ม แต่จะใช้เครื่องมือ Profiling

🛠 Step-by-step:

  1. The Inspector: รัน Node ด้วย Flag --inspect เพื่อเปิดพอร์ตให้ Chrome เข้าไปดูไส้ใน
  2. Heap Snapshot: ถ่ายรูปหน่วยความจำ (Snap 1) ตอนเริ่ม และถ่ายอีกรูป (Snap 2) ตอนแรมสูง
  3. Comparison: นำมาเทียบ "Diff" กัน เพื่อดูว่า Object ไหนที่งอกออกมาแล้วไม่ยอมหายไป (Garbage Collector ไม่เก็บ)
  4. Flame Graph: ดูกราฟเปลวไฟ เพื่อหาว่าฟังก์ชันไหนที่ "แถบแนวนอนยาวผิดปกติ" (นั่นคือจุดที่กิน CPU นานที่สุด)
HLJS BASH
# ✅ Best Practice: เปิดโหมดตรวจสอบ
node --inspect app.js # 🛠 แล้วเปิด chrome://inspect เพื่อเริ่มล่าบอส (Bugs)

🪤 4. The Junior Trap: โรค "Sync ใน Request"

จูเนียร์มักจะใช้ฟังก์ชันที่มีคำว่า Sync เพราะมันเขียนง่าย:

HLJS JAVASCRIPT
// ❌ Junior Trap: ขวางทางด่วนด้วยสิ่งกีดขวาง
app.get("/read-config", (req, res) => {
  const data = fs.readFileSync("large-file.txt"); // 🌋 พัง! คนอื่นทั้งเครื่องจะหยุดรอจนกว่าไฟล์นี้จะอ่านเสร็จ
  res.send(data);
});

ระวัง: คำว่า Sync ใน Node.js คือยาพิษสำหรับ High Traffic ✅ การแก้ไข: ใช้ fs.promises หรือเวอร์ชัน Callback เสมอ เพื่อให้เชฟ (Thread) ขยับไปรับงานคนอื่นได้ในขณะที่รอไฟล์โหลด


⚖️ 5. The Why Matrix: CPU vs Memory Problems

หัวข้อปัญหา CPU (Process)ปัญหา Memory (RAM)
อาการเว็บหน่วง, พัดลมเครื่องดัง, CPU 100%เว็บดับ (Crash), แรมเพิ่มเป็นขั้นบันได
สาเหตุหลักLoop เยอะเกิน, คำนวณ Hash, Regex หนักๆลืมลบ Global, Closure ค้าง, Listener รั่ว
เครื่องมือแก้Flame Graph / Performance TabHeap Snapshot / Allocation Timeline
ผลกระทบกระทบทุก Request ทันทีค่อยๆ ป่วย จนสุดท้ายตายสนิท

🎓 6. Senior Mindset Summary

การเป็น Senior คือการมองว่า "ความเร็วไม่ใช่แค่เรื่องของอัลกอริทึม แต่คือเรื่องของการบริหารจัดการเวลาของระบบ (Event Loop Management)". เว็บที่เสถียรไม่ใช่เว็บที่ไม่มีบั๊ก แต่คือเว็บที่เรารู้ว่า 'รูรั่ว' อยู่ตรงไหนและอุดมันได้ก่อนที่จะเกิดเรื่องใหญ่ครับ!

Share this note

© 2026 My Notes by Seereen