Performance
Web Development
Frontend
SEO
Core Web Vitals
Ask anything about this article
Hi! I've read this article.
What would you like to know?
@farhan
A 1-second delay in page load reduces conversions by 7%. Google uses Core Web Vitals as a ranking factor. Performance isn't optional — it's essential.
| Metric | Good | Needs Work | Poor |
|---|---|---|---|
| LCP (Largest Contentful Paint) | < 2.5s | 2.5-4s | > 4s |
| INP (Interaction to Next Paint) | < 200ms | 200-500ms | > 500ms |
| CLS (Cumulative Layout Shift) | < 0.1 | 0.1-0.25 | > 0.25 |
Images are typically 50-70% of page weight:
html<!-- Next.js Image component (automatic optimization) -->
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={630}
priority <!-- Above the fold: no lazy loading -->
sizes="(max-width: 768px) 100vw, 50vw"
quality={80}
/>
<!-- Native lazy loading for below-fold images -->
<img
src="photo.webp"
alt="Photo"
loading="lazy"
decoding="async"
width="800"
height="600"
/>
| Format | Quality | Size vs JPEG | Browser Support |
|---|---|---|---|
| WebP | Equal | -30% | 97% |
| AVIF | Better | -50% | 92% |
| JPEG XL | Better | -60% | 10% (limited) |
typescript// Before: imports everything upfront
import { HeavyChart } from './charts';
// After: loads only when needed
const HeavyChart = lazy(() => import('./charts'));
function Dashboard() {
return (
<Suspense fallback={<ChartSkeleton />}>
<HeavyChart data={data} />
</Suspense>
);
}
typescript// Bad: imports entire library (200KB)
import _ from 'lodash';
_.debounce(fn, 300);
// Good: imports only what's needed (2KB)
import debounce from 'lodash/debounce';
debounce(fn, 300);
Static assets (JS, CSS, images):
Cache-Control: public, max-age=31536000, immutable
HTML pages:
Cache-Control: public, max-age=0, must-revalidate
API responses:
Cache-Control: private, max-age=60, stale-while-revalidate=300
Every millisecond counts. Optimize relentlessly.