Performance Optimization Trade-offs
Frontend performance is full of trade-offs. Code splitting improves initial load but adds navigation latency. Lazy loading reduces bundle size but requires loading states. Image optimization shrinks payloads but increases build complexity. Great engineers understand both the wins and the hidden costs of each decision.
You have limited resources (bytes, CPU, network, developer time). Every optimization spends some of that budget to buy user experience improvements. The best decisions maximize user happiness per unit spent.
1Code Splitting & Lazy Loading
Route-based splitting for navigation and component-based splitting for heavy features. Use dynamic import() with proper loading states and prefetching on intent.
const openModal = async () => {
const { default: Modal } = await import('./HeavyModal');
setModal(Modal);
};2Bundle Size & Tree Shaking
Prefer named imports, avoid side effects, audit dependencies. Replace heavy libraries (Moment → date-fns, Material UI → Radix + Tailwind) when possible.
3Image & Asset Optimization
Use modern formats (WebP/AVIF), explicit dimensions, lazy loading, and CDN. Reserve space to prevent CLS.
4Core Web Vitals Trade-offs
LCP favors preloading and CDNs. INP requires task chunking and off-main-thread work. CLS demands layout stability at the cost of some flexibility.
| Property | Eager Loading | Lazy Loading |
|---|---|---|
| Cons | Larger initial bundle, Wasted bandwidth | Interaction delays, Loading states required |
| Pros | No loading delays, Simpler UX | Smaller initial load, Better LCP |
| Best For | Critical path, small apps | Large apps, below-fold content |
Eager Loading
Cons
Larger initial bundle, Wasted bandwidth
Pros
No loading delays, Simpler UX
Best For
Critical path, small apps
Lazy Loading
Cons
Interaction delays, Loading states required
Pros
Smaller initial load, Better LCP
Best For
Large apps, below-fold content
Common questions
- ›“How do you decide what to lazy load vs load eagerly?”
- ›“What are the trade-offs of code splitting?”
- ›“How do you balance bundle size with user experience?”
- ›“Walk through optimizing a slow page with poor Core Web Vitals.”
What interviewers look for
- Data-driven decision making (measure first)
- Understanding of user-perceived vs raw performance
- Awareness of hidden costs (complexity, loading states, CLS)
- Holistic thinking across loading, interactivity, and stability
Short answer (60 sec)
Prioritize user-visible bottlenecks. Use code splitting and lazy loading for non-critical code, optimize images aggressively, and always measure real-user impact. Every optimization has trade-offs — choose based on data, not dogma.
Detailed answer (senior level)
Performance is about trade-offs. Route-based and dynamic imports reduce initial bundle but add latency on navigation. Tree shaking and modern formats shrink payloads but require build discipline. Core Web Vitals force us to balance LCP (loading), INP (responsiveness), and CLS (stability). Senior engineers measure first, optimize high-impact areas, and accept complexity only when it delivers clear user value.
- Premature optimization without measuring
- Lazy loading critical above-the-fold content
- Forgetting loading states and error handling
- Over-splitting into too many tiny chunks
- Ignoring CLS when adding dynamic content
- ✓Measure real-user metrics before and after changes
- ✓Optimize for LCP first, then INP, then CLS
- ✓Lazy load heavy, non-critical features
- ✓Reserve space and use modern image formats
- ✓Tree-shake aggressively and audit dependencies
- ✓Balance performance gains with development and UX costs
- ✓Performance is a continuous process, not a one-time task