Last month, our e-commerce site was struggling with a 6.5s load time. Today, it loads in 2.1s. Here's exactly how we did it, with real code examples and results.
The Problem
Our Lighthouse scores were embarrassing:
- Performance: 45
- First Contentful Paint: 3.2s
- Largest Contentful Paint: 6.5s
- Time to Interactive: 7.8s
Users were leaving before the page even loaded. Here's how we fixed it.
1. Image Optimization Revolution 🖼️
Before:
<img src="hero-image.jpg" alt="Product showcase" />
After:
<!-- Using native lazy loading and WebP -->
<picture>
<source
srcset="hero-image.webp"
type="image/webp"
/>
<img
src="hero-image.jpg"
alt="Product showcase"
loading="lazy"
width="800"
height="600"
/>
</picture>
Result: 40% reduction in image load time
2. Critical CSS Extraction ⚡
We now inline critical CSS and defer non-critical styles:
<head>
<!-- Inlined critical CSS -->
<style>
/* Only styles needed for above-the-fold content */
.hero { ... }
.nav { ... }
</style>
<!-- Deferred non-critical CSS -->
<link
rel="preload"
href="styles.css"
as="style"
onload="this.onload=null;this.rel='stylesheet'"
/>
</head>
Result: First Paint improved by 1.2 seconds
3. JavaScript Diet Plan 🏋️♂️
Before:
<script src="jquery.min.js"></script>
<script src="massive-slider.js"></script>
<script src="analytics.js"></script>
After:
<!-- Only load what's needed -->
<script type="module">
// Dynamic import when needed
const showSlider = async () => {
const { createSlider } = await import('./tiny-slider.js');
createSlider();
}
// Load on user interaction
document.querySelector('.slider-btn')
.addEventListener('click', showSlider);
</script>
Result: JavaScript payload reduced by 65%
4. Smart Caching Strategy 🧠
// Service Worker Setup
const CACHE_VERSION = 'v1.2.0';
const CACHED_ASSETS = [
'/',
'/styles.css',
'/app.js',
'/fonts/roboto.woff2'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_VERSION)
.then(cache => cache.addAll(CACHED_ASSETS))
);
});
Result: Repeat visits load 80% faster
5. Font Loading Optimization 📝
<link
rel="preload"
href="/fonts/roboto.woff2"
as="font"
type="font/woff2"
crossorigin
/>
<style>
/* Font loading strategy */
@font-face {
font-family: 'Roboto';
font-display: swap;
src: url('/fonts/roboto.woff2') format('woff2');
}
</style>
Result: No more font flickering, faster text display
6. Component-Level Code Splitting 📦
// React example
const ProductGallery = React.lazy(() =>
import('./ProductGallery')
);
function Shop() {
return (
<Suspense fallback={<Spinner />}>
<ProductGallery />
</Suspense>
);
}
Result: Initial bundle size reduced by 45%
7. Smart Prefetching 🔄
// Prefetch on hover
const prefetchOnHover = (event) => {
const link = event.target.closest('a');
if (link && !prefetched.has(link.href)) {
const prefetcher = document.createElement('link');
prefetcher.rel = 'prefetch';
prefetcher.href = link.href;
document.head.appendChild(prefetcher);
prefetched.add(link.href);
}
}
document.addEventListener('mouseover', prefetchOnHover);
Result: Page transitions feel instant
8. API Response Optimization 📡
// Implementing field selection
const fetchProduct = async (id) => {
const fields = ['name', 'price', 'thumbnail'];
const response = await fetch(
`/api/products/${id}?fields=${fields.join(',')}`
);
return response.json();
}
Result: API responses 60% smaller
9. State Management Diet 🏃♂️
// Before: Everything in Redux
const store = createStore(rootReducer);
// After: Only what's needed
function ProductPage() {
const [product, setProduct] = useState(null);
const globalCart = useSelector(state => state.cart);
// Local state for UI
const [isLoading, setIsLoading] = useState(false);
const [selectedVariant, setSelectedVariant] = useState(null);
// ...
}
Result: Redux store size reduced by 70%
10. Build Optimization 🛠️
// webpack.config.js
module.exports = {
optimization: {
moduleIds: 'deterministic',
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
}
Result: 30% better caching, smaller builds
The Results 📊
After implementing these changes:
- Lighthouse Performance: 94
- First Contentful Paint: 1.1s
- Largest Contentful Paint: 2.1s
- Time to Interactive: 2.8s
Key Takeaways 🎯
- Start with measurement
- Optimize images aggressively
- Load JavaScript smartly
- Cache strategically
- Monitor continuously
Found this helpful? Follow for more web performance tips!
Drop a ❤️ if you're implementing any of these techniques.
What's your biggest performance challenge? Let me know in the comments!
#webdev #performance #javascript #webperf #optimization
Top comments (0)