Back to notes
mastery-frontend-typescript
Featured

JavaScript Performance: เทคนิคการเขียน JS ให้เร็วทะลุนรก

รวมเทคนิคการรีดประสิทธิภาพ JavaScript ตั้งแต่การใช้ Map แทน Array, การ Cache Property, ไปจนถึงการวนลูปแบบ Pro

January 29, 20262 min read readNNexis by Seereen

ภาพรวม (Overview)

บางทีเรามัวแต่ไป Optimize ที่ระดับ Framework (React/Vue) จนลืมไปว่า "พื้นฐาน" คือ JavaScript การเขียน JS ที่ดีช่วยให้เว็บเร็วขึ้นแบบไม่ต้องพึ่งท่าน่าพิสดาร วันนี้มาดูเทคนิค Micro-optimization ที่ Vercel Engineer แนะนำกันครับ

1. Index Maps: บอกลา O(N) ไปหา O(1)

ถ้าต้องเอาของใน Array A ไปหาใน Array B อย่าใช้ .find() ในลูปเด็ดขาด! เพราะมันจะกลายเป็น O(N²) (ช้ามากถ้าข้อมูลเยอะ)

❌ แบบช้า (O(N²)):

HLJS TYPESCRIPT
const orders = [
  /* 1000 items */
];
const users = [
  /* 1000 items */
];

// วนลูป order (1000 รอบ)
// ข้างในวนหา user (เฉลี่ย 500 รอบ)
// รวม = 500,000 operations!
const result = orders.map((order) => ({
  ...order,
  user: users.find((u) => u.id === order.userId),
}));

✅ แบบเร็ว (O(N)): สร้าง Map ไว้ก่อน ค้นหาทีหลังจะเร็วระดับ O(1)

HLJS TYPESCRIPT
// สร้าง Map ทีเดียว (1000 operations)
const userMap = new Map(users.map((u) => [u.id, u]));

// วนลูป order (1000 รอบ) x หาใน map (1 operation)
// รวม = 2,000 operations (เร็วกว่า 250 เท่า!)
const result = orders.map((order) => ({
  ...order,
  user: userMap.get(order.userId),
}));

2. Layout Thrashing: อย่าอ่านสลับเขียน

Browser จะทำงานหนักมากถ้าเรา "อ่านค่า Layout" (เช่น offsetWidth, clientHeight) สลับกับ "เขียนค่า Style" ไปมา เพราะทุกครั้งที่อ่าน Browser ต้องคำนวณ Layout ใหม่ทั้งหมด (Reflow)

❌ อ่านสลับเขียน (Force Reflow รัวๆ):

HLJS TYPESCRIPT
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");

box1.style.width = "100px"; // เขียน
console.log(box1.offsetWidth); // อ่าน -> บังคับ Reflow ทันที!

box2.style.width = "100px"; // เขียน
console.log(box2.offsetWidth); // อ่าน -> บังคับ Reflow อีกรอบ!

✅ เขียนให้หมดก่อน ค่อยอ่านทีเดียว:

HLJS TYPESCRIPT
// เขียนรวดเดียว (Browser จะ batch การเปลี่ยน style ไว้)
box1.style.width = "100px";
box2.style.width = "100px";

// อ่านทีเดียว (Browser คำนวณ Reflow แค่ครั้งเดียว)
console.log(box1.offsetWidth);
console.log(box2.offsetWidth);

3. Cache Property Access

การเข้าถึงตัวแปรที่ซ้อนลึกๆ (obj.a.b.c.d) ใน Loop กินทรัพยากรมากกว่าที่คิด เพราะ JS Engine ต้องวิ่งตาม Chain ไปเรื่อยๆ

❌ วิ่งหาของทุกรอบ:

HLJS TYPESCRIPT
for (let i = 0; i < 10000; i++) {
  // ต้องวิ่งหา config -> settings -> value หมื่นรอบ
  process(app.config.settings.value);
}

✅ ดึงมาถือไว้ก่อน:

HLJS TYPESCRIPT
// วิ่งหาทีเดียว
const value = app.config.settings.value;

for (let i = 0; i < 10000; i++) {
  process(value); // ใช้ตัวแปรโดยตรง เร็วกว่าเห็นๆ
}

4. Set/Map Lookups ดีกว่า Array.includes

ถ้าต้องเช็คว่า "มีของชิ้นนี้ไหม" ในรายการที่เยอะๆ ให้ใช้ Set แทน Array ครับ

❌ Array.includes (O(N)):

HLJS TYPESCRIPT
const blockedIds = [/* 10,000 IDs */];
// ต้องไล่เช็คทีละตัวจนกว่าจะเจอ
if (blockedIds.includes(currentId)) { ... }

✅ Set.has (O(1)):

HLJS TYPESCRIPT
const blockedSet = new Set(blockedIds);
// เช็คเปรี้ยงเดียวรู้เลย ไม่ว่าข้อมูลจะเยอะแค่ไหน
if (blockedSet.has(currentId)) { ... }

สรุป

Algorithm และ Data Structure พื้นฐานยังคงสำคัญที่สุดครับ

  1. ใช้ Map / Set เมื่อต้องค้นหาข้อมูล
  2. ระวังการอ่าน Layout (offsetWidth, etc.)
  3. Cache ตัวแปรใน Loop เสมอ

เขียน JS ให้ดี แล้ว Framework จะทำงานเบาลงครับ!

References

Share this note

© 2026 My Notes by Seereen