📚 Code Splitting & Lazy Loading Kya Hai?
Code Splitting ek technique hai jisme aap apne application ke code ko chhote-chhote bundles (chunks) mein divide karte ho. Iska matlab hai ki user ko sirf wahi code load hota hai jo use us waqt chahiye, baaki ka code baad mein on-demand load hota hai.
Lazy Loading iska implementation hai jisme components, routes, ya resources ko tab load kiya jata hai jab unki zaroorat ho. Isse initial page load time bahut kam ho jata hai aur application faster feel hoti hai.
Lazy Loading iska implementation hai jisme components, routes, ya resources ko tab load kiya jata hai jab unki zaroorat ho. Isse initial page load time bahut kam ho jata hai aur application faster feel hoti hai.
🎯 Kyun Zaroori Hai?
- Faster Initial Load: Kam code = Kam download time = Faster app
- Better Performance: Browser ko kam JavaScript parse aur execute karna padta hai
- Improved User Experience: Users ko jaldi content dikhta hai
- Reduced Bandwidth: Users sirf wahi download karte hain jo use karte hain
- Better Caching: Individual chunks cache ho sakte hain
70%
Bundle Size Reduction
3x
Faster Load Time
50%
Less Memory Usage
90+
Lighthouse Score
💡 Real-World Impact: Netflix ne code splitting implement karke apni initial load time 50% tak reduce kar di. Amazon ne dekha ki har 100ms ki delay se 1% revenue loss hota hai!
1️⃣ React.lazy & Suspense
React.lazy() ek function hai jo aapko components ko dynamically import karne deta hai. Yeh component tab load hota hai jab woh render hone wala ho. Suspense ek component hai jo loading state handle karta hai jab tak lazy component load nahi ho jata.
// Traditional Import (Eager Loading)
import HeavyComponent from './HeavyComponent';
// Lazy Import (On-Demand Loading)
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
// Usage with Suspense
import { lazy, Suspense } from 'react';
const Dashboard = lazy(() => import('./Dashboard'));
const Profile = lazy(() => import('./Profile'));
const Settings = lazy(() => import('./Settings'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Dashboard />
<Profile />
<Settings />
</Suspense>
);
}
🎮 Interactive Demo: React.lazy Loading
Click buttons to simulate lazy loading of components:
No component loaded yet. Click a button to see lazy loading in action!
📊 Loading Stats:
Components Loaded:
0
0
Total Size:
0 KB
0 KB
Load Time:
0s
0s
⚠️ Important Points:
•
•
• Server-side rendering (SSR) mein
• Multiple lazy components ek hi Suspense boundary share kar sakte hain
•
React.lazy sirf default exports ke saath kaam karta hai•
Suspense boundary zaroori hai, warna error aayega• Server-side rendering (SSR) mein
React.lazy directly kaam nahi karta• Multiple lazy components ek hi Suspense boundary share kar sakte hain
2️⃣ Dynamic Imports
Dynamic Imports JavaScript ka native feature hai jo aapko runtime pe modules import karne deta hai. Yeh
import() function use karta hai jo ek Promise return karta hai. React.lazy internally isi ko use karta hai, lekin aap ise directly bhi use kar sakte ho non-component code ke liye.
// Dynamic Import for Components
const loadComponent = async () => {
const module = await import('./MyComponent');
return module.default;
};
// Dynamic Import for Utilities
const loadUtility = async () => {
const { heavyFunction } = await import('./utils');
return heavyFunction();
};
// Dynamic Import for Libraries
const loadChart = async () => {
const Chart = await import('chart.js');
return new Chart(ctx, config);
};
// Conditional Dynamic Import
const loadFeature = async (featureName) => {
if (featureName === 'advanced') {
const module = await import('./AdvancedFeature');
return module.default;
}
};
// Error Handling
const safeImport = async () => {
try {
const module = await import('./Module');
return module.default;
} catch (error) {
console.error('Failed to load module', error);
return null;
}
};
🎮 Interactive Demo: Dynamic Import Scenarios
📊 Chart Library
250 KB
Heavy visualization library
Not Loaded
✏️ Rich Text Editor
180 KB
WYSIWYG editor component
Not Loaded
📄 PDF Viewer
320 KB
PDF rendering library
Not Loaded
🗺️ Map Component
400 KB
Interactive maps library
Not Loaded
💾 Current Bundle Size:
Click on any module above to dynamically import it
✅ Best Practices:
• Heavy libraries (charts, editors, maps) ko dynamically import karo
• User interaction ke baad load karo (button click, tab switch)
• Prefetching use karo agar aapko pata hai user kya use karega
• Error boundaries implement karo failed imports ke liye
• Heavy libraries (charts, editors, maps) ko dynamically import karo
• User interaction ke baad load karo (button click, tab switch)
• Prefetching use karo agar aapko pata hai user kya use karega
• Error boundaries implement karo failed imports ke liye
3️⃣ Route-based Code Splitting
Route-based Code Splitting sabse common aur effective approach hai. Isme har route (page) ko alag chunk mein split karte hain. Jab user kisi route pe jata hai, sirf usi route ka code load hota hai. Yeh React Router ke saath bahut achhe se kaam karta hai.
// Route-based Code Splitting with React Router
import { lazy, Suspense } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
// Lazy load all route components
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Profile = lazy(() => import('./pages/Profile'));
const Settings = lazy(() => import('./pages/Settings'));
// Loading component
const LoadingFallback = () => (
<div style={{ textAlign: 'center', padding: '50px' }}>
<div>Loading...</div>
</div>
);
function App() {
return (
<BrowserRouter>
<Suspense fallback={<LoadingFallback />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/profile" element={<Profile />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
</BrowserRouter>
);
}
🎮 Interactive Demo: Route-based Splitting
🧭 Navigation:
📍 Current Route: /home
🏠 Home Page
Welcome to the home page! This is loaded on demand.
📦 Loaded Chunks:
main.js
50 KB
50 KB
home.chunk.js
25 KB
25 KB
about.chunk.js
20 KB
20 KB
dashboard.chunk.js
45 KB
45 KB
profile.chunk.js
30 KB
30 KB
settings.chunk.js
35 KB
35 KB
4️⃣ Image Optimization & Lazy Loading
Image Lazy Loading ek technique hai jisme images tab load hoti hain jab woh viewport mein aane wali hoti hain. Images usually sabse bada resource hoti hain web pages mein, toh inhe optimize karna bahut zaroori hai. Modern browsers mein native lazy loading support hai.
// Native Lazy Loading (HTML)
<img
src="image.jpg"
loading="lazy"
alt="Description"
/>
// React Component with Lazy Loading
const LazyImage = ({ src, alt }) => {
const [isLoaded, setIsLoaded] = useState(false);
const [isInView, setIsInView] = useState(false);
const imgRef = useRef();
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsInView(true);
observer.disconnect();
}
},
{ threshold: 0.1 }
);
if (imgRef.current) {
observer.observe(imgRef.current);
}
return () => observer.disconnect();
}, []);
return (
<div ref={imgRef}>
{isInView ? (
<img
src={src}
alt={alt}
onLoad={() => setIsLoaded(true)}
style={{ opacity: isLoaded ? 1 : 0 }}
/>
) : (
<div>Loading...</div>
)}
</div>
);
};
// Progressive Image Loading
const ProgressiveImage = ({ placeholder, src, alt }) => {
const [imgSrc, setImgSrc] = useState(placeholder);
useEffect(() => {
const img = new Image();
img.src = src;
img.onload = () => {
setImgSrc(src);
};
}, [src]);
return (
<img
src={imgSrc}
alt={alt}
style={{
filter: imgSrc === placeholder ? 'blur(10px)' : 'none',
transition: 'filter 0.3s'
}}
/>
);
};
🎮 Interactive Demo: Image Lazy Loading
Click "Load Images" to simulate lazy loading:
Image 1
Not Loaded
Not Loaded
Image 2
Not Loaded
Not Loaded
Image 3
Not Loaded
Not Loaded
Image 4
Not Loaded
Not Loaded
Image 5
Not Loaded
Not Loaded
Image 6
Not Loaded
Not Loaded
📊 Loading Statistics:
0/6
Images Loaded
0 KB
Data Saved
0s
Load Time
💡 Image Optimization Tips:
• Modern formats use karo: WebP, AVIF (fallback ke saath)
• Responsive images:
• Proper dimensions set karo to avoid layout shift
• CDN use karo automatic optimization ke liye
• Placeholder images ya blur effect use karo better UX ke liye
• Modern formats use karo: WebP, AVIF (fallback ke saath)
• Responsive images:
srcset aur sizes attributes• Proper dimensions set karo to avoid layout shift
• CDN use karo automatic optimization ke liye
• Placeholder images ya blur effect use karo better UX ke liye
5️⃣ Chunk Splitting Best Practices
Chunk Splitting ka matlab hai apne code ko intelligent tareeke se divide karna. Webpack aur modern bundlers automatically yeh karte hain, lekin aap configuration se ise optimize kar sakte ho. Sahi chunking strategy se caching improve hoti hai aur users ko kam data download karna padta hai.
// Webpack Configuration for Chunk Splitting
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
// Vendor chunk - Third-party libraries
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10
},
// Common chunk - Shared code
common: {
minChunks: 2,
priority: 5,
reuseExistingChunk: true
},
// React chunk - Separate React libraries
react: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: 'react',
priority: 20
}
}
}
}
};
// Vite Configuration
export default {
build: {
rollupOptions: {
output: {
manualChunks: {
'react-vendor': ['react', 'react-dom'],
'router': ['react-router-dom'],
'ui-library': ['@mui/material']
}
}
}
}
};
// Magic Comments for Webpack
const HeavyComponent = lazy(() =>
import(
/* webpackChunkName: "heavy-component" */
/* webpackPrefetch: true */
'./HeavyComponent'
)
);
🎮 Interactive Demo: Chunk Strategy Comparison
❌ Poor Strategy
main.bundle.js
850 KB
850 KB
- Single large bundle
- Slow initial load
- Poor caching
- Wasted bandwidth
✅ Optimal Strategy
main.js
50 KB
50 KB
vendors.js
200 KB
200 KB
home.js
30 KB
30 KB
dashboard.js
45 KB
45 KB
chart.js
120 KB
120 KB
- Multiple optimized chunks
- Fast initial load (80 KB)
- Better caching
- On-demand loading
📊 Performance Comparison:
| Metric | Poor Strategy | Optimal Strategy | Improvement |
|---|---|---|---|
| Initial Load | 850 KB | 80 KB | 90% faster |
| Parse Time | 2.5s | 0.3s | 88% faster |
| Cache Hit Rate | 20% | 85% | 325% better |
| Time to Interactive | 4.8s | 1.2s | 75% faster |
✅ Chunking Best Practices:
1. Vendor Chunks: Third-party libraries ko alag chunk mein rakho (rarely change hoti hain)
2. Common Chunks: Shared code ko extract karo to avoid duplication
3. Route Chunks: Har route ko alag chunk (automatic with lazy loading)
4. Size Limits: Chunks ko 200-300 KB se chhota rakho
5. Prefetching: Critical chunks ko prefetch karo
6. Naming: Meaningful chunk names use karo debugging ke liye
1. Vendor Chunks: Third-party libraries ko alag chunk mein rakho (rarely change hoti hain)
2. Common Chunks: Shared code ko extract karo to avoid duplication
3. Route Chunks: Har route ko alag chunk (automatic with lazy loading)
4. Size Limits: Chunks ko 200-300 KB se chhota rakho
5. Prefetching: Critical chunks ko prefetch karo
6. Naming: Meaningful chunk names use karo debugging ke liye
⚠️ Common Mistakes:
• Bahut zyada chhote chunks (overhead badh jata hai)
• Vendor chunk mein sab kuch daal dena (better to split by usage)
• Dynamic imports ko ignore karna
• Cache busting strategy na hona
• Bundle analyzer na use karna
• Bahut zyada chhote chunks (overhead badh jata hai)
• Vendor chunk mein sab kuch daal dena (better to split by usage)
• Dynamic imports ko ignore karna
• Cache busting strategy na hona
• Bundle analyzer na use karna
🚀 Advanced Techniques
Prefetching & Preloading
Prefetching aur Preloading techniques hain jo future mein zaroorat padne wale resources ko pehle se load kar leti hain. Isse user experience smooth ho jata hai kyunki jab user actually resource use karta hai, woh already loaded hota hai.
// Prefetch - Low priority, load when browser is idle
const AdminPanel = lazy(() =>
import(
/* webpackPrefetch: true */
'./AdminPanel'
)
);
// Preload - High priority, load immediately
const CriticalComponent = lazy(() =>
import(
/* webpackPreload: true */
'./CriticalComponent'
)
);
// Manual Prefetching
const prefetchComponent = () => {
const link = document.createElement('link');
link.rel = 'prefetch';
link.href = '/static/js/dashboard.chunk.js';
document.head.appendChild(link);
};
// Prefetch on hover
const handleMouseEnter = () => {
import('./HeavyComponent');
};
<button onMouseEnter={handleMouseEnter}>
Dashboard
</button>
Error Boundaries for Lazy Components
// Error Boundary for handling lazy loading failures
class LazyLoadErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error('Lazy loading failed:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<div>
<h2>Failed to load component</h2>
<button onClick={() => window.location.reload()}>
Retry
</button>
</div>
);
}
return this.props.children;
}
}
// Usage
<LazyLoadErrorBoundary>
<Suspense fallback={<Loading />}>
<LazyComponent />
</Suspense>
</LazyLoadErrorBoundary>
Measuring Performance
// Performance monitoring
const measureLoadTime = async (componentName) => {
const startTime = performance.now();
try {
await import(`./components/${componentName}`);
const endTime = performance.now();
const loadTime = endTime - startTime;
console.log(`${componentName} loaded in ${loadTime}ms`);
// Send to analytics
analytics.track('component_load', {
component: componentName,
loadTime: loadTime
});
} catch (error) {
console.error(`Failed to load ${componentName}`, error);
}
};
🎯 Interview Questions
Yeh questions aapki Code Splitting & Lazy Loading understanding ko test karenge!
Easy
Q1: React.lazy aur Suspense kya hain? Yeh kaise kaam karte hain?
Answer:
React.lazy(): Ek function hai jo dynamic import ko accept karta hai aur ek React component return karta hai. Yeh component tab load hota hai jab woh pehli baar render hone wala ho.
Suspense: Ek component hai jo lazy components ke loading state ko handle karta hai. Jab tak lazy component load nahi hota, tab tak Suspense apna fallback UI show karta hai.
Working:
1. React.lazy() ek Promise return karta hai
2. Jab component render hota hai, React us Promise ko resolve karta hai
3. Tab tak Suspense fallback show karta hai
4. Promise resolve hone ke baad actual component render hota hai
Example:
Important: React.lazy sirf default exports ke saath kaam karta hai.
React.lazy(): Ek function hai jo dynamic import ko accept karta hai aur ek React component return karta hai. Yeh component tab load hota hai jab woh pehli baar render hone wala ho.
Suspense: Ek component hai jo lazy components ke loading state ko handle karta hai. Jab tak lazy component load nahi hota, tab tak Suspense apna fallback UI show karta hai.
Working:
1. React.lazy() ek Promise return karta hai
2. Jab component render hota hai, React us Promise ko resolve karta hai
3. Tab tak Suspense fallback show karta hai
4. Promise resolve hone ke baad actual component render hota hai
Example:
const MyComponent = lazy(() => import('./MyComponent'));<Suspense fallback={<Loading />}><MyComponent /></Suspense>Important: React.lazy sirf default exports ke saath kaam karta hai.
Easy
Q2: Code splitting se kya benefits milte hain? Real-world example do.
Answer:
Benefits:
1. Faster Initial Load: Kam code download = Faster page load
2. Better Performance: Browser ko kam JavaScript parse karna padta hai
3. Improved Caching: Individual chunks cache ho sakte hain
4. Reduced Bandwidth: Users sirf zaroorat ka code download karte hain
5. Better User Experience: Content jaldi dikhta hai
Real-World Example - E-commerce Site:
Without Code Splitting:
• Initial bundle: 800 KB
• Load time: 4.5 seconds
• User ko sab kuch download karna padta hai (admin panel, checkout, product reviews, etc.)
With Code Splitting:
• Initial bundle: 150 KB (home page)
• Load time: 1.2 seconds
• Admin panel (200 KB) - sirf admin users ke liye load hota hai
• Checkout (100 KB) - sirf jab user checkout pe jaye
• Product reviews (80 KB) - sirf jab user reviews tab khole
Result: 70% faster initial load, better conversion rate!
Benefits:
1. Faster Initial Load: Kam code download = Faster page load
2. Better Performance: Browser ko kam JavaScript parse karna padta hai
3. Improved Caching: Individual chunks cache ho sakte hain
4. Reduced Bandwidth: Users sirf zaroorat ka code download karte hain
5. Better User Experience: Content jaldi dikhta hai
Real-World Example - E-commerce Site:
Without Code Splitting:
• Initial bundle: 800 KB
• Load time: 4.5 seconds
• User ko sab kuch download karna padta hai (admin panel, checkout, product reviews, etc.)
With Code Splitting:
• Initial bundle: 150 KB (home page)
• Load time: 1.2 seconds
• Admin panel (200 KB) - sirf admin users ke liye load hota hai
• Checkout (100 KB) - sirf jab user checkout pe jaye
• Product reviews (80 KB) - sirf jab user reviews tab khole
Result: 70% faster initial load, better conversion rate!
Medium
Q3: Route-based code splitting aur component-based code splitting mein kya difference hai? Kab kaunsa use karoge?
Answer:
Route-based Code Splitting:
• Har route (page) ko alag chunk mein split karte hain
• User jab route change karta hai tab load hota hai
• Sabse common aur recommended approach
• Natural split point hai application mein
Example:
Component-based Code Splitting:
• Individual heavy components ko split karte hain
• Component jab render hone wala ho tab load hota hai
• Specific use cases ke liye
• Fine-grained control milta hai
Example:
Kab Kaunsa Use Karein:
Route-based use karo jab:
• Application mein multiple pages hain
• Clear navigation structure hai
• Har page independent functionality hai
• Starting point chahiye code splitting ke liye
Component-based use karo jab:
• Heavy third-party libraries use kar rahe ho (charts, editors)
• Conditional rendering hai (modals, tabs)
• User interaction ke baad load karna hai
• Route-based splitting ke saath combine karke
Best Practice: Dono ko combine karo - routes ko split karo, aur heavy components ko bhi!
Route-based Code Splitting:
• Har route (page) ko alag chunk mein split karte hain
• User jab route change karta hai tab load hota hai
• Sabse common aur recommended approach
• Natural split point hai application mein
Example:
const Home = lazy(() => import('./pages/Home'));const Dashboard = lazy(() => import('./pages/Dashboard'));Component-based Code Splitting:
• Individual heavy components ko split karte hain
• Component jab render hone wala ho tab load hota hai
• Specific use cases ke liye
• Fine-grained control milta hai
Example:
const ChartComponent = lazy(() => import('./Chart'));const RichTextEditor = lazy(() => import('./Editor'));Kab Kaunsa Use Karein:
Route-based use karo jab:
• Application mein multiple pages hain
• Clear navigation structure hai
• Har page independent functionality hai
• Starting point chahiye code splitting ke liye
Component-based use karo jab:
• Heavy third-party libraries use kar rahe ho (charts, editors)
• Conditional rendering hai (modals, tabs)
• User interaction ke baad load karna hai
• Route-based splitting ke saath combine karke
Best Practice: Dono ko combine karo - routes ko split karo, aur heavy components ko bhi!
Medium
Q4: Webpack ke splitChunks configuration ko explain karo. Vendor chunks kyun important hain?
Answer:
splitChunks Configuration:
Webpack ka optimization feature hai jo automatically code ko multiple chunks mein divide karta hai based on certain rules.
Key Options:
•
•
•
•
•
Vendor Chunks Kyun Important Hain:
1. Caching Benefits:
• Third-party libraries rarely change hoti hain
• Ek baar load ho gayi toh cache mein reh sakti hain
• Har deployment pe users ko download nahi karni padti
2. Parallel Loading:
• Browser multiple chunks parallel mein download kar sakta hai
• Vendor chunk aur app chunk simultaneously load ho sakte hain
3. Better Organization:
• Your code aur third-party code separate
• Debugging aur analysis easy ho jata hai
4. Optimal Size:
• Large vendor libraries ko separate rakhne se main bundle chhota rehta hai
Example Configuration:
Result:
• main.js (50 KB) - Your app code
• react.js (120 KB) - React libraries (cached)
• vendors.js (200 KB) - Other libraries (cached)
• Total initial: 370 KB, but 320 KB cached on repeat visits!
splitChunks Configuration:
Webpack ka optimization feature hai jo automatically code ko multiple chunks mein divide karta hai based on certain rules.
Key Options:
•
chunks: 'all' - All chunks ko split karo (async + sync)•
minSize - Minimum chunk size•
maxSize - Maximum chunk size•
minChunks - Kitni baar use hona chahiye•
cacheGroups - Custom splitting rulesVendor Chunks Kyun Important Hain:
1. Caching Benefits:
• Third-party libraries rarely change hoti hain
• Ek baar load ho gayi toh cache mein reh sakti hain
• Har deployment pe users ko download nahi karni padti
2. Parallel Loading:
• Browser multiple chunks parallel mein download kar sakta hai
• Vendor chunk aur app chunk simultaneously load ho sakte hain
3. Better Organization:
• Your code aur third-party code separate
• Debugging aur analysis easy ho jata hai
4. Optimal Size:
• Large vendor libraries ko separate rakhne se main bundle chhota rehta hai
Example Configuration:
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
priority: 10
},
react: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: 'react',
priority: 20
}
}
}Result:
• main.js (50 KB) - Your app code
• react.js (120 KB) - React libraries (cached)
• vendors.js (200 KB) - Other libraries (cached)
• Total initial: 370 KB, but 320 KB cached on repeat visits!
Medium
Q5: Prefetching aur Preloading mein kya difference hai? Kab kaunsa use karoge?
Answer:
Prefetching:
• Low priority resource loading
• Browser idle hone pe load hota hai
• Future navigation ke liye
•
Preloading:
• High priority resource loading
• Immediately load hota hai
• Current page ke liye critical resources
•
Detailed Comparison:
Kab Prefetch Use Karein:
• Next page jo user visit kar sakta hai
• Dashboard link pe hover karne pe
• Login ke baad dashboard prefetch karo
• Analytics se predict karo user kahan jayega
Example:
Kab Preload Use Karein:
• Critical fonts jo immediately chahiye
• Above-the-fold images
• Critical CSS
• Hero section resources
Example:
⚠️ Warning: Preload ka overuse mat karo, warna bandwidth waste hoga aur actual performance kharab ho jayega!
Prefetching:
• Low priority resource loading
• Browser idle hone pe load hota hai
• Future navigation ke liye
•
<link rel="prefetch">Preloading:
• High priority resource loading
• Immediately load hota hai
• Current page ke liye critical resources
•
<link rel="preload">Detailed Comparison:
| Feature | Prefetch | Preload |
|---|---|---|
| Priority | Low | High |
| When | Browser idle time | Immediately |
| Use Case | Future pages | Current page |
| Cache | HTTP cache | Memory cache |
Kab Prefetch Use Karein:
• Next page jo user visit kar sakta hai
• Dashboard link pe hover karne pe
• Login ke baad dashboard prefetch karo
• Analytics se predict karo user kahan jayega
Example:
const Dashboard = lazy(() => import(/* webpackPrefetch: true */ './Dashboard'));Kab Preload Use Karein:
• Critical fonts jo immediately chahiye
• Above-the-fold images
• Critical CSS
• Hero section resources
Example:
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>⚠️ Warning: Preload ka overuse mat karo, warna bandwidth waste hoga aur actual performance kharab ho jayega!
Hard
Q6: Image lazy loading implement karne ke different approaches kya hain? Intersection Observer API ko detail mein explain karo.
Answer:
Image Lazy Loading Approaches:
1. Native Lazy Loading:
• HTML attribute:
• Browser built-in support
• Sabse simple approach
• Limited customization
2. Intersection Observer API:
• Modern JavaScript API
• Viewport visibility detect karta hai
• Highly customizable
• Better performance than scroll events
Intersection Observer Detailed Explanation:
Kya Hai:
Ek API jo asynchronously observe karta hai ki ek element viewport mein visible hai ya nahi. Yeh scroll events se better hai kyunki yeh main thread ko block nahi karta.
Kaise Kaam Karta Hai:
1. Observer create karo with callback function
2. Target elements ko observe karo
3. Jab element viewport mein aaye, callback trigger hota hai
4. Callback mein image load karo
5. Observer disconnect karo
Implementation:
3. React Implementation:
4. Progressive Image Loading:
• Pehle low-quality placeholder load karo
• Phir high-quality image load karo
• Smooth transition effect
Benefits of Intersection Observer:
• No scroll event listeners (better performance)
• Asynchronous (non-blocking)
• Customizable thresholds
• Root margin for early loading
• Multiple elements efficiently observe kar sakta hai
Browser Support: 95%+ modern browsers (polyfill available for older browsers)
Image Lazy Loading Approaches:
1. Native Lazy Loading:
• HTML attribute:
loading="lazy"• Browser built-in support
• Sabse simple approach
• Limited customization
<img src="image.jpg" loading="lazy" alt="Description">2. Intersection Observer API:
• Modern JavaScript API
• Viewport visibility detect karta hai
• Highly customizable
• Better performance than scroll events
Intersection Observer Detailed Explanation:
Kya Hai:
Ek API jo asynchronously observe karta hai ki ek element viewport mein visible hai ya nahi. Yeh scroll events se better hai kyunki yeh main thread ko block nahi karta.
Kaise Kaam Karta Hai:
1. Observer create karo with callback function
2. Target elements ko observe karo
3. Jab element viewport mein aaye, callback trigger hota hai
4. Callback mein image load karo
5. Observer disconnect karo
Implementation:
const imageObserver = new IntersectionObserver(
(entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // Load actual image
img.classList.add('loaded');
observer.unobserve(img); // Stop observing
}
});
},
{
root: null, // viewport
rootMargin: '50px', // Load 50px before visible
threshold: 0.1 // 10% visible hone pe trigger
}
);
// Observe all lazy images
document.querySelectorAll('img[data-src]').forEach(img => {
imageObserver.observe(img);
});3. React Implementation:
const LazyImage = ({ src, alt }) => {
const [isLoaded, setIsLoaded] = useState(false);
const [isInView, setIsInView] = useState(false);
const imgRef = useRef();
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsInView(true);
observer.disconnect();
}
},
{ threshold: 0.1, rootMargin: '100px' }
);
if (imgRef.current) {
observer.observe(imgRef.current);
}
return () => observer.disconnect();
}, []);
return (
<div ref={imgRef}>
{isInView ? (
<img
src={src}
alt={alt}
onLoad={() => setIsLoaded(true)}
style={{
opacity: isLoaded ? 1 : 0,
transition: 'opacity 0.3s'
}}
/>
) : (
<div className="placeholder">Loading...</div>
)}
</div>
);
};4. Progressive Image Loading:
• Pehle low-quality placeholder load karo
• Phir high-quality image load karo
• Smooth transition effect
Benefits of Intersection Observer:
• No scroll event listeners (better performance)
• Asynchronous (non-blocking)
• Customizable thresholds
• Root margin for early loading
• Multiple elements efficiently observe kar sakta hai
Browser Support: 95%+ modern browsers (polyfill available for older browsers)
Hard
Q7: Production environment mein code splitting failures ko kaise handle karoge? Error boundaries aur retry mechanisms explain karo.
Answer:
Code Splitting Failures Kyun Hoti Hain:
• Network issues (slow/unstable connection)
• Chunk files not found (deployment issues)
• Browser cache issues
• CDN failures
• Version mismatches
Comprehensive Error Handling Strategy:
1. Error Boundary Implementation:
2. Retry Mechanism with Exponential Backoff:
3. Fallback Component Strategy:
4. Version Mismatch Detection:
5. Monitoring & Analytics:
6. Complete Production Setup:
Best Practices:
• Multiple layers of error boundaries
• Automatic retry with exponential backoff
• User-friendly error messages
• Analytics tracking for monitoring
• Version checking mechanism
• Graceful degradation with fallbacks
• Clear cache on version updates
• Network status detection
Result: Robust production app jo failures ko gracefully handle karta hai aur users ko smooth experience deta hai!
Code Splitting Failures Kyun Hoti Hain:
• Network issues (slow/unstable connection)
• Chunk files not found (deployment issues)
• Browser cache issues
• CDN failures
• Version mismatches
Comprehensive Error Handling Strategy:
1. Error Boundary Implementation:
class LazyLoadErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
retryCount: 0
};
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
// Log to error tracking service
console.error('Lazy load failed:', error, errorInfo);
// Send to analytics
analytics.track('lazy_load_error', {
error: error.message,
component: this.props.componentName,
retryCount: this.state.retryCount
});
}
handleRetry = () => {
this.setState(prevState => ({
hasError: false,
error: null,
retryCount: prevState.retryCount + 1
}));
};
handleReload = () => {
window.location.reload();
};
render() {
if (this.state.hasError) {
return (
<div className="error-container">
<h2>Failed to load component</h2>
<p>{this.state.error?.message}</p>
{this.state.retryCount < 3 ? (
<button onClick={this.handleRetry}>
Retry ({this.state.retryCount}/3)
</button>
) : (
<button onClick={this.handleReload}>
Reload Page
</button>
)}
</div>
);
}
return this.props.children;
}
}2. Retry Mechanism with Exponential Backoff:
const lazyWithRetry = (componentImport, retries = 3, interval = 1000) => {
return new Promise((resolve, reject) => {
componentImport()
.then(resolve)
.catch((error) => {
if (retries === 0) {
reject(error);
return;
}
setTimeout(() => {
console.log(`Retrying... (${retries} attempts left)`);
lazyWithRetry(componentImport, retries - 1, interval * 2)
.then(resolve)
.catch(reject);
}, interval);
});
});
};
// Usage
const Dashboard = lazy(() =>
lazyWithRetry(() => import('./Dashboard'))
);3. Fallback Component Strategy:
const LazyComponentWrapper = ({
importFunc,
fallbackComponent: FallbackComponent
}) => {
const [Component, setComponent] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
importFunc()
.then(module => setComponent(() => module.default))
.catch(err => {
setError(err);
// Load fallback
if (FallbackComponent) {
setComponent(() => FallbackComponent);
}
});
}, []);
if (error && !Component) {
return <ErrorDisplay error={error} />;
}
if (!Component) {
return <LoadingSpinner />;
}
return <Component />;
};4. Version Mismatch Detection:
// Store app version in localStorage
const APP_VERSION = '1.2.3';
const checkVersion = () => {
const storedVersion = localStorage.getItem('appVersion');
if (storedVersion && storedVersion !== APP_VERSION) {
// New version deployed, clear cache
if ('caches' in window) {
caches.keys().then(names => {
names.forEach(name => caches.delete(name));
});
}
localStorage.setItem('appVersion', APP_VERSION);
window.location.reload(true);
} else {
localStorage.setItem('appVersion', APP_VERSION);
}
};
// Call on app initialization
checkVersion();5. Monitoring & Analytics:
const trackLazyLoadMetrics = (componentName, success, loadTime, error) => {
// Send to analytics service
analytics.track('lazy_load_metrics', {
component: componentName,
success: success,
loadTime: loadTime,
error: error?.message,
userAgent: navigator.userAgent,
connection: navigator.connection?.effectiveType,
timestamp: Date.now()
});
};6. Complete Production Setup:
// App.js
function App() {
return (
<LazyLoadErrorBoundary componentName="App">
<Suspense fallback={<LoadingScreen />}>
<Router>
<Routes>
<Route
path="/dashboard"
element={
<LazyLoadErrorBoundary componentName="Dashboard">
<Suspense fallback={<PageLoader />}>
<Dashboard />
</Suspense>
</LazyLoadErrorBoundary>
}
/>
</Routes>
</Router>
</Suspense>
</LazyLoadErrorBoundary>
);
}Best Practices:
• Multiple layers of error boundaries
• Automatic retry with exponential backoff
• User-friendly error messages
• Analytics tracking for monitoring
• Version checking mechanism
• Graceful degradation with fallbacks
• Clear cache on version updates
• Network status detection
Result: Robust production app jo failures ko gracefully handle karta hai aur users ko smooth experience deta hai!