Optymalizacja wydajności Next.js - 10 sprawdzonych technik
Praktyczny przewodnik po optymalizacji aplikacji Next.js. Dowiedz się, jak poprawić Core Web Vitals i przyspieszyć swoją stronę.
Dlaczego wydajność ma znaczenie?
W 2025 roku szybkość strony to nie tylko nice-to-have - to must-have. Google priorytetyzuje szybkie strony w wynikach wyszukiwania, a użytkownicy opuszczają wolne witryny w ciągu sekund.
Fakty o wydajności:
- 53% użytkowników mobile opuszcza stronę, która ładuje się dłużej niż 3 sekundy
- Każda sekunda opóźnienia może zmniejszyć konwersję o 7%
- Strony w top 10% pod względem wydajności mają 2x wyższy współczynnik konwersji
1. Wykorzystaj Server Components
Next.js 15 wprowadza Server Components jako domyślne. To rewolucyjna zmiana!
Przed (Client Component):
'use client';
import { useState, useEffect } from 'react';
export default function Posts() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('/api/posts')
.then(res => res.json())
.then(setPosts);
}, []);
return <div>{/* render posts */}</div>;
}Po (Server Component):
// app/blog/page.tsx
export default async function BlogPage() {
const posts = await fetch('https://api.example.com/posts').then(r => r.json());
return (
<div>
{posts.map(post => (
<article key={post.id}>{post.title}</article>
))}
</div>
);
}Korzyści:
- ✅ Zero JavaScript wysłanego do klienta
- ✅ Dane pobierane na serwerze (szybciej)
- ✅ Lepsze SEO
2. Optymalizuj obrazy z next/image
Next.js ma wbudowany komponent Image, który automatycznie:
- Generuje responsywne rozmiary
- Lazy loaduje obrazy
- Konwertuje do WebP/AVIF
- Zapobiega Cumulative Layout Shift (CLS)
import Image from 'next/image';
export function Hero() {
return (
<Image
src="/hero.jpg"
alt="Hero image"
width={1200}
height={600}
priority // dla above-the-fold images
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>
);
}Pro tip: Użyj priority tylko dla obrazów above-the-fold!
3. Implementuj Static Generation (SSG)
Statyczne strony są ultra-szybkie i tanie w hostingu.
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
export default async function BlogPost({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug);
return <article>{/* render post */}</article>;
}Kiedy używać SSG:
- ✅ Strony, które rzadko się zmieniają
- ✅ Blogi, portfolio, landing pages
- ✅ Dokumentacja
4. Używaj dynamicznych importów
Ładuj komponenty tylko wtedy, gdy są potrzebne:
import dynamic from 'next/dynamic';
const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
loading: () => <p>Ładowanie wykresu...</p>,
ssr: false, // nie renderuj na serwerze
});
export default function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
<HeavyChart />
</div>
);
}Oszczędzasz: Nawet 200-300KB JavaScript bundle!
5. Optymalizuj fonty
Next.js 15 ma wbudowaną optymalizację fontów:
// app/layout.tsx
import { Inter, Poppins } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
variable: '--font-inter',
});
const poppins = Poppins({
subsets: ['latin'],
weight: ['400', '600', '700'],
display: 'swap',
variable: '--font-poppins',
});
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="pl" className={`${inter.variable} ${poppins.variable}`}>
<body>{children}</body>
</html>
);
}Korzyści:
- ✅ Self-hosted fonts (privacy!)
- ✅ Zero layout shift
- ✅ Automatyczna optymalizacja
6. Konfiguruj caching mądrze
// app/blog/page.tsx
export const revalidate = 3600; // revalidate co godzinę
export default async function BlogPage() {
const posts = await fetch('https://api.example.com/posts', {
next: { revalidate: 3600 }
}).then(r => r.json());
return <div>{/* posts */}</div>;
}Strategie:
- Static data →
revalidate: false - Często aktualizowana →
revalidate: 60 - Real-time →
revalidate: 0lub Client Component
7. Używaj React Server Actions
Zamiast API routes, użyj Server Actions:
// app/contact/page.tsx
async function submitForm(formData: FormData) {
'use server';
const email = formData.get('email');
// Process form server-side
await saveToDatabase(email);
}
export default function ContactPage() {
return (
<form action={submitForm}>
<input name="email" type="email" />
<button type="submit">Wyślij</button>
</form>
);
}Zalety:
- ✅ Mniej boilerplate
- ✅ Automatyczna walidacja
- ✅ Better UX
8. Monitoring z Vercel Analytics
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
{children}
<Analytics />
</body>
</html>
);
}Śledź:
- Core Web Vitals (LCP, FID, CLS)
- Real User Monitoring
- Geographic performance
9. Prefetch Links
Next.js automatycznie prefetchuje linki w viewport:
import Link from 'next/link';
export function Navigation() {
return (
<nav>
<Link href="/about" prefetch={true}>
O nas
</Link>
<Link href="/blog" prefetch={false}>
Blog {/* nie prefetchuj */}
</Link>
</nav>
);
}10. Bundle Analyzer
Zidentyfikuj, co spowalnia Twoją aplikację:
npm install @next/bundle-analyzer// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
// ... config
});Uruchom:
ANALYZE=true npm run buildChecklist optymalizacji
Przed deploy upewnij się, że:
- Używasz Server Components gdzie to możliwe
- Wszystkie obrazy przez
next/image - Fonty zoptymalizowane przez
next/font - Heavy components lazy-loaded
- Odpowiednie revalidate dla cached data
- Lighthouse score > 90
- Core Web Vitals w zielonym zakresie
Narzędzia do testowania
- Lighthouse - wbudowany w Chrome DevTools
- PageSpeed Insights - Google's tool
- WebPageTest - szczegółowa analiza
- Vercel Analytics - real user monitoring
Realne rezultaty
Po zastosowaniu tych technik w projektach naszych klientów:
- 📈 LCP poprawiony z 4.2s → 1.1s
- 📈 FID poprawiony z 180ms → 45ms
- 📈 Bundle size zmniejszony o 60%
- 📈 Conversion rate wzrósł o 34%
Podsumowanie
Optymalizacja Next.js to proces ciągły, nie jednorazowa akcja. Kluczowe zasady:
- Measure first - nie optymalizuj na ślepo
- Server > Client - wykorzystuj Server Components
- Lazy load everything - ładuj tylko to, co potrzebne
- Cache aggressively - ale mądrze
- Monitor constantly - śledź metryki
Potrzebujesz pomocy z optymalizacją?
W Bitspire specjalizujemy się w budowaniu ultra-szybkich aplikacji Next.js. Skontaktuj się z nami, aby dowiedzieć się, jak możemy poprawić wydajność Twojej strony.