Performance Optimization Techniques
Performance optimization is crucial for providing a good user experience. Understanding various optimization techniques helps build faster and more efficient applications.
Code Optimization
// Memoization
const memoize = (fn) => {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn(...args);
cache.set(key, result);
return result;
};
};
// Debouncing
function debounce(fn, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
}
// Throttling
function throttle(fn, limit) {
let inThrottle;
return function (...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}Loading Optimization
// Lazy loading components
const LazyComponent = React.lazy(() =>
import('./HeavyComponent')
);
// Dynamic imports
async function loadModule() {
const module = await import('./large-module.js');
module.doSomething();
}
// Image loading
<img
loading="lazy"
srcset="small.jpg 300w, medium.jpg 600w"
sizes="(max-width: 600px) 300px, 600px"
src="fallback.jpg"
alt="Optimized image"
/>React Performance
// Using memo
const MemoizedComponent = React.memo(function MyComponent(props) {
return <div>{props.data}</div>;
});
// useMemo for expensive calculations
const memoizedValue = useMemo(() =>
computeExpensiveValue(a, b),
[a, b]
);
// useCallback for callbacks
const memoizedCallback = useCallback(
() => doSomething(a, b),
[a, b]
);
// Virtual list for large datasets
function VirtualList({ items }) {
return (
<VirtualScroll
itemCount={items.length}
itemSize={50}
renderItem={({ index, style }) => (
<div style={style}>{items[index]}</div>
)}
/>
);
}Network Optimization
// Caching responses
const cache = new Cache();
async function fetchWithCache(url) {
const cached = await cache.match(url);
if (cached) return cached;
const response = await fetch(url);
cache.put(url, response.clone());
return response;
}
// Request batching
class RequestBatcher {
queue = [];
timeout = null;
add(request) {
this.queue.push(request);
if (!this.timeout) {
this.timeout = setTimeout(() => this.flush(), 100);
}
}
async flush() {
const requests = this.queue;
this.queue = [];
this.timeout = null;
return batchRequest(requests);
}
}Common Interview Follow-up Questions
- How do you identify performance bottlenecks?
- What tools do you use for performance monitoring?
- How do you optimize React component rendering?
- What are the best practices for code splitting?
Best Practices
- Measure before optimizing
- Use appropriate caching strategies
- Implement code splitting
- Optimize images and assets
- Minimize network requests
- Use performance monitoring tools