## What is Web Performance Optimization?
Web performance optimization is making websites load faster and run smoother. Every millisecond counts - faster sites rank higher in Google, convert more users, and cost less to run.
Amazon found that every 100ms of latency costs them 1% in sales. Google found that 53% of mobile users abandon sites that take over 3 seconds to load.
Speed is not a nice-to-have. It is a business requirement.
## Why Performance Matters
**User Experience**: Nobody waits for slow websites. They bounce to competitors.
**SEO**: Google ranks fast sites higher. Core Web Vitals are ranking factors.
**Conversions**: Faster sites make more money. Pinterest increased conversions 15% by reducing load time 40%.
**Costs**: Faster sites use less bandwidth and fewer server resources.
**Accessibility**: Slow sites hurt users on poor networks or old devices most.
## Core Web Vitals (What Google Measures)
**Largest Contentful Paint (LCP)**: How long until main content loads. Target: under 2.5 seconds.
**First Input Delay (FID)**: How long until page responds to interaction. Target: under 100ms.
**Cumulative Layout Shift (CLS)**: How much content jumps around while loading. Target: under 0.1.
Google uses these metrics for ranking. Optimize these first.
## Loading Performance
**Minimize File Sizes**:
Compress images:
```bash
# Use modern formats
WebP instead of JPEG/PNG (30-50% smaller)
AVIF even better (50% smaller than WebP)
# Responsive images
<img srcset="small.jpg 480w, large.jpg 1080w"
sizes="(max-width: 600px) 480px, 1080px">
```
Minify code:
```bash
# JavaScript, CSS, HTML
npm install terser cssnano html-minifier
# Result: 40-60% smaller files
```
**Lazy Loading**:
Load images when needed:
```html
<img src="image.jpg" loading="lazy">
```
Lazy load JavaScript:
```javascript
// Load component only when needed
const HeavyComponent = lazy(() => import("./Heavy"))
```
**Code Splitting**:
Split JavaScript into chunks:
```javascript
// Next.js does this automatically
// Manually with dynamic imports
import("./module").then(module => {
module.doSomething()
})
```
Each page loads only code it needs.
**Critical CSS**:
Inline CSS for above-the-fold content:
```html
<style>
/* Critical styles inline */
.header { /* ... */ }
</style>
<link rel="stylesheet" href="non-critical.css" media="print"
onload="this.media='all'">
```
Page renders instantly, rest loads later.
## Network Optimization
**Use a CDN**:
Serve static files from edge servers worldwide:
- Cloudflare (free tier available)
- AWS CloudFront
- Vercel (automatic for Next.js)
- Netlify (automatic)
Users get files from nearest server. Massive speed boost.
**Enable Compression**:
Enable Gzip or Brotli compression:
```nginx
# Nginx config
gzip on;
gzip_types text/plain text/css application/json application/javascript;
```
Text files compress 70-90%. Huge bandwidth savings.
**HTTP/2 and HTTP/3**:
Modern protocols are faster:
- Multiplexing (multiple files in parallel)
- Header compression
- Server push
Most hosts support HTTP/2 now. Enable it.
**Reduce HTTP Requests**:
Combine files where possible:
```html
<!-- Bad: 5 requests -->
<script src="lib1.js"></script>
<script src="lib2.js"></script>
<script src="lib3.js"></script>
<script src="lib4.js"></script>
<script src="lib5.js"></script>
<!-- Good: 1 request -->
<script src="bundle.js"></script>
```
## Rendering Performance
**Avoid Layout Thrashing**:
Bad code (forces multiple reflows):
```javascript
for (let i = 0; i < 100; i++) {
const width = element.offsetWidth // Read
element.style.width = width + 10 // Write
// Browser reflows 100 times!
}
```
Good code (batch reads and writes):
```javascript
const width = element.offsetWidth // Read once
for (let i = 0; i < 100; i++) {
element.style.width = width + 10 // Write all
}
// Browser reflows once
```
**Use CSS Transforms**:
CSS transforms are GPU-accelerated:
```css
/* Slow (triggers layout) */
.box { left: 100px; }
/* Fast (GPU accelerated) */
.box { transform: translateX(100px); }
```
**Debounce Expensive Operations**:
```javascript
// Resize handler fires 100+ times per second
window.addEventListener("resize", () => {
recalculateLayout() // Too expensive!
})
// Debounced - fires once when resizing stops
window.addEventListener("resize", debounce(() => {
recalculateLayout() // Much better
}, 250))
```
## JavaScript Performance
**Defer Non-Critical Scripts**:
```html
<!-- Blocks rendering -->
<script src="heavy.js"></script>
<!-- Better: loads asynchronously -->
<script src="heavy.js" async></script>
<!-- Best: loads after page interactive -->
<script src="heavy.js" defer></script>
```
**Tree Shaking**:
Remove unused code:
```javascript
// Import only what you need
import { debounce } from "lodash-es" // Good (4KB)
// Not this
import _ from "lodash" // Bad (70KB with unused code)
```
Modern bundlers eliminate dead code automatically.
**Optimize Loops**:
```javascript
// Slow - accesses length every iteration
for (let i = 0; i < array.length; i++) { }
// Fast - cache length
const len = array.length
for (let i = 0; i < len; i++) { }
// Fastest - use built-in methods
array.forEach(item => { })
```
## Caching Strategies
**Browser Cache Headers**:
```http
# Cache static assets for 1 year
Cache-Control: public, max-age=31536000, immutable
# Cache HTML for 1 hour
Cache-Control: public, max-age=3600
```
**Service Workers**:
Cache assets for offline use:
```javascript
self.addEventListener("install", event => {
event.waitUntil(
caches.open("v1").then(cache => {
return cache.addAll([
"/",
"/styles.css",
"/app.js"
])
})
)
})
```
**Server-Side Caching**:
Cache expensive operations:
- Redis for database query results
- Varnish for HTTP responses
- CDN edge caching
## Database Performance
**Add Indexes**:
```sql
-- Slow query (scans millions of rows)
SELECT * FROM users WHERE email = 'john@example.com'
-- Fast query with index (instant lookup)
CREATE INDEX idx_email ON users(email)
```
**Optimize Queries**:
```sql
-- Bad (fetches everything)
SELECT * FROM users
-- Good (only needed columns)
SELECT id, name, email FROM users
-- Best (with limit)
SELECT id, name, email FROM users LIMIT 20
```
**Use Connection Pooling**:
Reuse database connections instead of creating new ones.
## Monitoring Performance
**Lighthouse**:
Built into Chrome DevTools. Run audits to get performance scores and suggestions.
**WebPageTest**:
Test from real devices and locations worldwide. Shows waterfall charts and film strips.
**Google PageSpeed Insights**:
Tests real user metrics. Shows Core Web Vitals scores.
**Real User Monitoring (RUM)**:
Track actual user performance:
- Google Analytics
- New Relic
- Datadog
## Performance Budget
Set maximum limits:
```javascript
{
"budget": [
{
"resourceSizes": [
{ "resourceType": "script", "budget": 250 },
{ "resourceType": "image", "budget": 500 }
]
}
]
}
```
CI fails if bundle exceeds limits. Prevents performance regressions.
## Quick Wins (Biggest Impact, Least Effort)
1. **Enable Compression**: Gzip/Brotli saves 70%+ bandwidth
2. **Use a CDN**: Serve files from edge, instant global speed
3. **Optimize Images**: Convert to WebP, compress properly
4. **Lazy Load Images**: Load only when visible
5. **Minify Code**: Remove whitespace and comments
6. **Enable Caching**: Proper cache headers save repeat loads
7. **Defer Non-Critical JS**: Let page become interactive faster
These seven changes can reduce load time by 50-70%.
## Mobile Optimization
**Reduce JavaScript**:
Mobile devices have slower CPUs. Less JavaScript means faster parsing and execution.
**Optimize for 3G**:
Test on slow networks:
```bash
# Chrome DevTools
Network tab → Throttle to "Slow 3G"
```
**Responsive Images**:
Serve appropriate sizes for mobile screens. No need to load desktop-size images on phones.
## Advanced Techniques
**Preload Critical Resources**:
```html
<link rel="preload" href="font.woff2" as="font">
<link rel="preload" href="hero.jpg" as="image">
```
Browser loads these immediately.
**DNS Prefetch**:
```html
<link rel="dns-prefetch" href="https://api.example.com">
```
Resolve DNS early for faster API calls.
**Resource Hints**:
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="prefetch" href="/next-page.html">
```
## Common Mistakes
**Premature Optimization**: Optimize based on data, not guesses
**Over-Optimizing**: Diminishing returns after the big wins
**Ignoring Mobile**: Most traffic is mobile now
**No Monitoring**: Cannot improve what you do not measure
**Breaking User Experience**: Speed should not break functionality
## The Bottom Line
Web performance optimization is an ongoing process, not a one-time task. Start with the quick wins that provide the biggest impact, then iterate based on real user data.
Fast sites make more money, rank higher, and provide better user experiences. The investment in performance pays dividends in user satisfaction and business results.
Measure first, optimize second, and never stop improving. Your users will thank you with their time, attention, and money.