# JavaScript/Node.js Performance Optimization **Load this file when:** Optimizing performance in JavaScript or Node.js projects ## Profiling Tools ### Node.js Built-in Profiler ```bash # CPU profiling node --prof app.js node --prof-process isolate-0x*.log > processed.txt # Inspect with Chrome DevTools node --inspect app.js # Open chrome://inspect # Heap snapshots node --inspect --inspect-brk app.js # Take heap snapshots in DevTools ``` ### Clinic.js Suite ```bash # Install clinic npm install -g clinic # Doctor - Overall health check clinic doctor -- node app.js # Flame - Flamegraph profiling clinic flame -- node app.js # Bubbleprof - Async operations clinic bubbleprof -- node app.js # Heap profiler clinic heapprofiler -- node app.js ``` ### Performance Measurement ```bash # 0x - Flamegraph generator npx 0x app.js # autocannon - HTTP load testing npx autocannon http://localhost:3000 # lighthouse - Frontend performance npx lighthouse https://example.com ``` ## V8 Optimization Patterns ### Hidden Classes and Inline Caches ```javascript // Bad: Dynamic property addition breaks hidden class function Point(x, y) { this.x = x; this.y = y; } const p1 = new Point(1, 2); p1.z = 3; // Deoptimizes! // Good: Consistent object shape function Point(x, y, z = 0) { this.x = x; this.y = y; this.z = z; // Always present } ``` ### Avoid Polymorphism in Hot Paths ```javascript // Bad: Type changes break optimization function add(a, b) { return a + b; } add(1, 2); // Optimized for numbers add("a", "b"); // Deoptimized! Now handles strings too // Good: Separate functions for different types function addNumbers(a, b) { return a + b; // Always numbers } function concatStrings(a, b) { return a + b; // Always strings } ``` ### Array Optimization ```javascript // Bad: Mixed types in array const mixed = [1, "two", 3, "four"]; // Slow property access // Good: Homogeneous arrays const numbers = [1, 2, 3, 4]; // Fast element access const strings = ["one", "two", "three"]; // Use typed arrays for numeric data const buffer = new Float64Array(1000); // Faster than regular arrays ``` ## Event Loop Optimization ### Avoid Blocking the Event Loop ```javascript // Bad: Synchronous operations block event loop const data = fs.readFileSync('large-file.txt'); const result = heavyComputation(data); // Good: Async operations const data = await fs.promises.readFile('large-file.txt'); const result = await processAsync(data); // For CPU-intensive work, use worker threads const { Worker } = require('worker_threads'); const worker = new Worker('./cpu-intensive.js'); ``` ### Batch Async Operations ```javascript // Bad: Sequential async calls for (const item of items) { await processItem(item); // Waits for each } // Good: Parallel execution await Promise.all(items.map(item => processItem(item))); // Better: Controlled concurrency with p-limit const pLimit = require('p-limit'); const limit = pLimit(10); // Max 10 concurrent await Promise.all( items.map(item => limit(() => processItem(item))) ); ``` ## Memory Management ### Avoid Memory Leaks ```javascript // Bad: Global variables and closures retain memory let cache = {}; // Never cleared function addToCache(key, value) { cache[key] = value; // Grows indefinitely } // Good: Use WeakMap for caching const cache = new WeakMap(); function addToCache(obj, value) { cache.set(obj, value); // Auto garbage collected } // Good: Implement cache eviction const LRU = require('lru-cache'); const cache = new LRU({ max: 500 }); ``` ### Stream Large Data ```javascript // Bad: Load entire file in memory const data = await fs.promises.readFile('large-file.txt'); const processed = data.toString().split('\n').map(process); // Good: Stream processing const readline = require('readline'); const stream = fs.createReadStream('large-file.txt'); const rl = readline.createInterface({ input: stream }); for await (const line of rl) { process(line); // Process one line at a time } ``` ## Database Query Optimization ### Connection Pooling ```javascript // Bad: Create new connection per request async function query(sql) { const conn = await mysql.createConnection(config); const result = await conn.query(sql); await conn.end(); return result; } // Good: Use connection pool const pool = mysql.createPool(config); async function query(sql) { return pool.query(sql); // Reuses connections } ``` ### Batch Database Operations ```javascript // Bad: Multiple round trips for (const user of users) { await db.insert('users', user); } // Good: Single batch insert await db.batchInsert('users', users, 1000); // Chunks of 1000 ``` ## HTTP Server Optimization ### Compression ```javascript const compression = require('compression'); app.use(compression({ level: 6, // Balance between speed and compression threshold: 1024 // Only compress responses > 1KB })); ``` ### Caching Headers ```javascript app.get('/static/*', (req, res) => { res.setHeader('Cache-Control', 'public, max-age=31536000'); res.setHeader('ETag', computeETag(file)); res.sendFile(file); }); ``` ### Keep-Alive Connections ```javascript const http = require('http'); const server = http.createServer({ keepAlive: true, keepAliveTimeout: 60000 // 60 seconds }, app); ``` ## Frontend Performance ### Code Splitting ```javascript // Dynamic imports for code splitting const HeavyComponent = lazy(() => import('./HeavyComponent')); // Route-based code splitting const routes = [ { path: '/dashboard', component: lazy(() => import('./Dashboard')) } ]; ``` ### Memoization ```javascript // React.memo for expensive components const ExpensiveComponent = React.memo(({ data }) => { return
{expensiveRender(data)}
; }); // useMemo for expensive computations const sortedData = useMemo(() => { return data.sort(compare); }, [data]); // useCallback for stable function references const handleClick = useCallback(() => { doSomething(id); }, [id]); ``` ### Virtual Scrolling ```javascript // For large lists, render only visible items import { FixedSizeList } from 'react-window'; {Row} ``` ## Performance Anti-Patterns ### Unnecessary Re-renders ```javascript // Bad: Creates new object on every render function MyComponent() { const style = { color: 'red' }; // New object each render return
Text
; } // Good: Define outside or use useMemo const style = { color: 'red' }; function MyComponent() { return
Text
; } ``` ### Expensive Operations in Render ```javascript // Bad: Expensive computation in render function MyComponent({ items }) { const sorted = items.sort(); // Sorts on every render! return ; } // Good: Memoize expensive computations function MyComponent({ items }) { const sorted = useMemo(() => items.sort(), [items]); return ; } ``` ## Benchmarking ### Simple Benchmarks ```javascript const { performance } = require('perf_hooks'); function benchmark(fn, iterations = 1000) { const start = performance.now(); for (let i = 0; i < iterations; i++) { fn(); } const end = performance.now(); console.log(`Avg: ${(end - start) / iterations}ms`); } benchmark(() => myFunction()); ``` ### Benchmark.js ```javascript const Benchmark = require('benchmark'); const suite = new Benchmark.Suite; suite .add('Array#forEach', function() { [1,2,3].forEach(x => x * 2); }) .add('Array#map', function() { [1,2,3].map(x => x * 2); }) .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').map('name')); }) .run(); ``` ## Performance Checklist **Before Optimizing:** - [ ] Profile with Chrome DevTools or clinic.js - [ ] Identify hot paths and bottlenecks - [ ] Measure baseline performance **Node.js Optimizations:** - [ ] Use worker threads for CPU-intensive tasks - [ ] Implement connection pooling for databases - [ ] Enable compression middleware - [ ] Use streams for large data processing - [ ] Implement caching (Redis, in-memory) - [ ] Batch async operations with controlled concurrency - [ ] Monitor event loop lag **Frontend Optimizations:** - [ ] Implement code splitting - [ ] Use React.memo for expensive components - [ ] Implement virtual scrolling for large lists - [ ] Optimize bundle size (tree shaking, minification) - [ ] Use Web Workers for heavy computations - [ ] Implement service workers for offline caching - [ ] Lazy load images and components **After Optimizing:** - [ ] Re-profile to verify improvements - [ ] Check memory usage for leaks - [ ] Run load tests (autocannon, artillery) - [ ] Monitor with APM tools ## Tools and Libraries **Profiling:** - `clinic.js` - Performance profiling suite - `0x` - Flamegraph profiler - `node --inspect` - Chrome DevTools integration - `autocannon` - HTTP load testing **Optimization:** - `p-limit` - Concurrency control - `lru-cache` - LRU caching - `compression` - Response compression - `react-window` - Virtual scrolling - `workerpool` - Worker thread pools **Monitoring:** - `prom-client` - Prometheus metrics - `newrelic` / `datadog` - APM - `clinic-doctor` - Health diagnostics --- *JavaScript/Node.js-specific performance optimization with V8 patterns and profiling tools*