Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

วิธีปรับปรุงประสิทธิภาพ JavaScript (Performance Optimization)

การเพิ่มประสิทธิภาพ JavaScript ทำให้แอปพลิเคชันทำงานเร็วขึ้น ตอบสนองดีขึ้น และใช้ทรัพยากรน้อยลง นี่คือเทคนิคหลัก:

1. การจัดการตัวแปรและหน่วยความจำ

สร้างตัวแปรเฉพาะที่จำเป็น

// ❌ ไม่ดี: สร้างตัวแปรไม่จำเป็น
let a = 1, b = 2, c = 3, d = a + b + c;

// ✅ ดี: สร้างเฉพาะที่ใช้ คำนวณทันที
const sum = 1 + 2 + 3;

หลีกเลี่ยง with Statement

// ❌ ไม่ดี: with ทำให้ Scope Chain ยาวขึ้น Engine ไม่สามารถ Optimize ได้
with (obj) { x = 1; y = 2; }

// ✅ ดี: ใช้ตัวแปรชี้ตรง
const { x, y } = obj;
x = 1; y = 2;

2. Loop Optimization (การเพิ่มประสิทธิภาพ Loop)

Cache Length / ใช้ For Loop แบบคลาสสิก

// ❌ ช้า: เข้าถึง .length ทุกครั้ง (สำหรับ Array-Like/HTMLCollection)
for (let i = 0; i < arr.length; i++) { ... }

// ✅ เร็ว: Cache Length
for (let i = 0, len = arr.length; i < len; i++) { ... }

// ✅ เร็วกว่า: Reverse Loop (ถ้าลำดับไม่สำคัญ)
for (let i = arr.length - 1; i >= 0; i--) { ... }

// ✅ สำหรับ Array จริง: forEach, for...of (Engine Optimize ให้แล้ว)
arr.forEach(item => { ... });
for (const item of arr) { ... }

3. DOM Manipulation (การจัดการ DOM)

Batch DOM Updates (รวมการเปลี่ยนแปลง)

// ❌ ช้า: Reflow/Repaint ทุก Iteration
items.forEach(item => {
  const div = document.createElement('div');
  div.textContent = item;
  container.appendChild(div);
});

// ✅ เร็ว: DocumentFragment / innerHTML
const fragment = document.createDocumentFragment();
items.forEach(item => {
  const div = document.createElement('div');
  div.textContent = item;
  fragment.appendChild(div);
});
container.appendChild(fragment); // 1 Reflow

// หรือสร้าง HTML String แล้ว innerHTML ครั้งเดียว (ระวัง XSS)
container.innerHTML = items.map(item => `
${escapeHtml(item)}
`).join('');

หลีกเลี่ยง Forced Synchronous Layout (Layout Thrashing)

// ❌ ไม่ดี: Read -> Write -> Read -> Write (บังคับ Layout ซ้ำ)
element.style.width = '100px';
const w = element.offsetWidth; // Force Layout
element.style.height = '200px';
const h = element.offsetHeight; // Force Layout

// ✅ ดี: Read ทั้งหมดก่อน Write ทั้งหมด
const w = element.offsetWidth;
const h = element.offsetHeight;
element.style.width = '100px';
element.style.height = '200px';

4. Event Handling

Event Delegation (ผูก Event ที่ Parent)

// ❌ ผูก Event ให้ทุก Child (Memory Heavy)
document.querySelectorAll('.item').forEach(btn => {
  btn.addEventListener('click', handleClick);
});

// ✅ ผูกที่ Parent 1 ตัว
document.getElementById('list').addEventListener('click', (e) => {
  if (e.target.matches('.item')) handleClick(e);
});

Passive Event Listeners (สำหรับ Scroll/Touch)

// บอก Browser ว่าไม่มี preventDefault() -> ไม่บล็อก Scroll
element.addEventListener('touchstart', handler, { passive: true });
element.addEventListener('wheel', handler, { passive: true });

5. Algorithms & Data Structures

  • ใช้ Set/Map แทน Array สำหรับ Lookup (O(1) vs O(n))
  • Memoization สำหรับ Function ที่คำนวณซ้ำ (Pure Functions)
  • Debounce / Throttle สำหรับ Event ที่ยิงบ่อย (Resize, Scroll, Input)
  • Web Workers สำหรับ Heavy Computation (Off Main Thread)

6. Loading & Parsing

  • Defer/Async Scripts: <script src="..." defer> (ตามลำดับหลัง Parse HTML), async (โหลดขนาน)
  • Code Splitting / Lazy Load: import('./module.js') โหลดเฉพาะต้องการ
  • Minify + Compress (Gzip/Brotli) ลดขนาดไฟล์
  • Tree Shaking: ลบ Dead Code (Webpack, Rollup, Vite)

7. Memory Management

  • หลีกเลี่ยง Global Variables (Memory Leak)
  • ล้าง Event Listeners, Timers, Observers เมื่อไม่ใช้ (removeEventListener, clearInterval, observer.disconnect())
  • ใช้ WeakMap, WeakSet, WeakRef สำหรับ Cache ที่ให้ GC เก็บได้

เครื่องมือวัดผล (Profiling Tools)

  • Chrome DevTools Performance Tab - Flame Chart, Call Tree, Memory Heap Snapshot
  • Lighthouse - Audit Performance, Best Practices
  • web-vitals Library - วัด Core Web Vitals (LCP, FID, CLS)
  • Benchmark.js - Microbenchmarks

สรุป Checklist

  1. ✅ Cache Loop Length / ใช้ for...of
  2. ✅ Batch DOM Updates (DocumentFragment)
  3. ✅ Avoid Layout Thrashing (Read-Read-Write-Write)
  4. ✅ Event Delegation + Passive Listeners
  5. ✅ Set/Map สำหรับ Lookup, Memoization
  6. ✅ Defer/Async Scripts, Code Splitting
  7. ✅ Cleanup Listeners/Timers/Observers
  8. ✅ Profile ด้วย DevTools ก่อน Optimize

หลักการ: "Measure first, optimize bottlenecks, avoid premature optimization" - วัดหาจุดคอขวดจริง แล้วค่อยปรับ