Back
Web Fundamentals

Performance Optimization Trade-offs

Web Fundamentals
Build & Deployment: Monorepo, CI/CD, Strategies & Release SafetyState Management: Choosing the Right SolutionRedux: Predictable State Container (RTK + RTK Query)React Query (TanStack Query): Server State CachingData Fetching Patterns: REST, GraphQL, tRPC & Real-timeGraphQL Fundamentals for Frontend: Shape, Caching, and TradeoffsgRPC-Web Fundamentals: Browser Constraints and Proxy ModelCaching Strategies: Client, Server & EdgeData Normalization: Organizing State for PerformanceAPI Design Best Practices: Pagination, Errors, Versioning & Type SafetyAPI Versioning Strategies for Frontend CompatibilityPagination: Offset vs Cursor-BasedRate Limiting & API Resilience: Retries, Backoff, Jitter, IdempotencyHow Frontend Developers Can Handle Millions of API Requests Without Crashing EverythingBrowser Storage: Cookies, SessionStorage, LocalStorage, IndexedDBReal-time Communication: WebSockets, SSE & PollingWebRTC: Real-Time Communication in the BrowserCore Web Vitals: LCP, INP & CLSPerformance Optimization Trade-offsCritical Resource Prioritization: Optimize Loading OrderCode Splitting: Optimize Bundle Size with Dynamic ImportsTree Shaking: Eliminate Dead Code from Your BundleLazy Loading: Load Resources On-DemandResource Hints: Preload, Prefetch & PreconnectText Compression: Gzip and BrotliImage & Video Optimization: Modern Formats & TechniquesAdaptive Loading: Optimize for Device & NetworkList Virtualization: Render Large Lists EfficientlyWeb Workers vs Main Thread: Offloading Heavy WorkMemory Leaks in Frontend Apps: Detection & PreventionManaging Third-Party Scripts: Optimization StrategiesHow CDNs Work: Edge Delivery, Caching & PerformanceHTTP Caching Deep Dive: Cache-Control, ETag & RevalidationService Workers & Offline Strategy: Cache First, Network First & Update LifecyclePWA Fundamentals: Manifest, Installability & Offline UXCritical Rendering PathScript Loading: async vs deferEvent Loop: Understanding JavaScript Execution ModelJavaScript Module Systems: CJS vs ESM vs UMDDynamic Module Loading: import() FunctionImport on Interaction: Load When User InteractsImport on Visibility: Lazy Loading with IntersectionObserverBrowser Rendering Pipeline & Layout ThrashingRendering Strategies: CSR vs SSR vs SSG vs ISRStreaming SSR: Progressive HTML StreamingIslands Architecture: Independent Component HydrationReact Server Components: Zero-JS Server RenderingFramework Reactivity: React, Vue, Svelte & SolidHTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC) for Frontend PerformanceDNS Resolution: Path, TTL, Caching & Frontend ImpactCross-Site Scripting (XSS) AttacksCross-Site Request Forgery (CSRF) AttacksCORS Explained: Cross-Origin Resource SharingCORS Preflight in Practice: Credentials, Simple Requests & MisconfigurationsContent Security Policy (CSP)Why is HTTPS Secure? Understanding TLS/SSLAuthorization Best PracticesCookie Security & Session Hardening: SameSite, HttpOnly, Secure
mediumPerformance

Performance Optimization Trade-offs

TL;DROptimize for user-visible bottlenecks first. Every gain has a cost — measure, prioritize, and trade wisely.
High Signal
Google
Meta
Netflix
Agoda
30-Second Answerstart every interview with this

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.

Identify Bottleneck
Choose Technique
Apply + Measure Impact
Accept Trade-off

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.

lazy-modal.tsxtsx
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.

PropertyEager LoadingLazy Loading
ConsLarger initial bundle, Wasted bandwidthInteraction delays, Loading states required
ProsNo loading delays, Simpler UXSmaller initial load, Better LCP
Best ForCritical path, small appsLarge 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
Key Takeaways
  • ✓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
Previous TopicCore Web Vitals: LCP, INP & CLSNext Topic Critical Resource Prioritization: Optimize Loading Order

On this page