การเพิ่มประสิทธิภาพ 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
- ✅ Cache Loop Length / ใช้ for...of
- ✅ Batch DOM Updates (DocumentFragment)
- ✅ Avoid Layout Thrashing (Read-Read-Write-Write)
- ✅ Event Delegation + Passive Listeners
- ✅ Set/Map สำหรับ Lookup, Memoization
- ✅ Defer/Async Scripts, Code Splitting
- ✅ Cleanup Listeners/Timers/Observers
- ✅ Profile ด้วย DevTools ก่อน Optimize
หลักการ: "Measure first, optimize bottlenecks, avoid premature optimization" - วัดหาจุดคอขวดจริง แล้วค่อยปรับ