Performance Optimization Trade-offs
Frontend Performance Strategy Map
Web FundamentalsSelective Rendering
Render only what users can see
- - Virtualize long lists
- - Defer below-the-fold UI
Chunk Smartly
Split by route and heavy feature
- - Route chunks for navigation
- - Component chunks for modals/charts
Loading Order
Prioritize user-visible work first
- - HTML/CSS for first paint
- - JS after critical content
Prefetch with Intent
Warm likely next interactions
- - Hover-based prefetch
- - Idle-time prefetch
Dynamic Imports
Load capabilities at interaction time
- - Editors/charts on demand
- - Feature flags by context
Bundle Hygiene
Keep shipped JS intentional
- - Tree-shake dead exports
- - Audit dependency weight
Cost Model First
Performance decisions should map to where time is spent: network, parse/execute, render, and interaction latency.
Fast Navigation Path
Interview Heuristic
The question is not "what can I optimize?" It is "what user-visible bottleneck do I remove first?"
Balancing performance optimizations with development complexity and user experience.
Note: These are brief techniques and trade-offs. Detailed explanations and implementation guides are available in the individual sections below.
Quick Navigation: Code Splitting • Lazy Loading • Bundle Size • Images • Core Web Vitals
Code Splitting Strategies
Route-Based Splitting
Split code by page/route. Each route loads its own bundle.
Pros
- ✓ Natural split points
- ✓ Easy to implement (Next.js automatic)
- ✓ Good for large apps
Cons
- ✗ Loading delay on navigation
- ✗ May not be enough for large pages
Component-Based Splitting
Split heavy components (modals, charts, editors).
Pros
- ✓ Fine-grained control
- ✓ Load only when needed
- ✓ Smaller initial bundle
Cons
- ✗ More complex implementation
- ✗ Need loading states
- ✗ Can cause layout shift
Vendor Splitting
Separate third-party libraries into their own chunk.
Pros
- ✓ Better caching (vendors rarely change)
- ✓ Parallel loading
Cons
- ✗ Additional HTTP requests
- ✗ May increase total bytes
Lazy Loading Trade-offs
Eager Loading
Load everything upfront.
🎯 Best For: Small apps, critical features
Lazy Loading
Load on demand (visibility, interaction).
🎯 Best For: Large apps, below-fold content
Lazy Loading Triggers
On Visibility
Load when element enters viewport (Intersection Observer)
On Interaction
Load on hover, click, or focus
On Idle
Load when browser is idle (requestIdleCallback)
Bundle Size vs Features
Library Selection Trade-offs
| Need | Heavy Option | Light Option |
|---|---|---|
| Date handling | Moment.js (~70KB) | date-fns (~7KB tree-shaken) |
| State management | Redux (~15KB) | Zustand (~1KB) |
| Animation | Framer Motion (~50KB) | CSS animations (0KB) |
| UI Components | Material UI (~100KB+) | Radix + Tailwind (~20KB) |
Tree Shaking Considerations
- Named imports:
import { specific } from 'lib'- tree-shakeable - Default imports:
import lib from 'lib'- often includes everything - Side effects: Some libraries have side effects that prevent tree shaking
Image Optimization
Format Trade-offs
| Format | Best For | Trade-off |
|---|---|---|
| WebP | Most images (photos, graphics) | 30% smaller than JPEG/PNG |
| AVIF | Highest compression | Limited browser support |
| SVG | Icons, logos, illustrations | Complex SVGs can be large |
| JPEG | Photos (fallback) | Larger, lossy compression |
Loading Strategies
Eager (Above the fold)
- • Priority loading for LCP images
- • Use preload for critical images
- • Avoid layout shift with dimensions
Lazy (Below the fold)
- • Native:
loading="lazy" - • Placeholder with blur-up
- • Intersection Observer for control
Core Web Vitals Trade-offs
LCP (Largest Contentful Paint)
Time until largest content element is visible.
Optimize
- • Preload LCP image
- • Optimize server response time
- • Use CDN for static assets
Trade-off
- • More preloads = more bandwidth
- • SSR adds server complexity
INP (Interaction to Next Paint)
Responsiveness to user interactions.
Optimize
- • Break up long tasks
- • Use web workers for heavy computation
- • Debounce/throttle handlers
Trade-off
- • More complex code architecture
- • Web workers add overhead
CLS (Cumulative Layout Shift)
Visual stability - elements shifting unexpectedly.
Optimize
- • Reserve space for dynamic content
- • Set explicit image dimensions
- • Avoid inserting content above existing
Trade-off
- • Skeleton screens add complexity
- • Fixed dimensions limit flexibility
Best Practices
- 1.Measure first. Use Lighthouse, WebPageTest, or RUM before optimizing.
- 2.Prioritize user-perceived performance. LCP and INP matter most.
- 3.Use framework features. Next.js Image, automatic code splitting.
- 4.Avoid premature optimization. Ship first, optimize based on data.
- 5.Set performance budgets. Fail CI if bundle exceeds threshold.