Оптимизация
Next.js даёт встроенные инструменты для оптимизации.
Изображения
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority
/>
Автоматически:
- Конвертирует в WebP/AVIF
- Ресайзит под экран
- Ленивая загрузка
- Предотвращает layout shift
Локальные изображения
import hero from '@/public/hero.jpg';
<Image src={hero} alt="Hero" placeholder="blur" />
Импорт даёт размеры автоматически.
Внешние изображения
next.config.ts:
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
},
],
},
};
Шрифты
import { Inter, Roboto } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
export default function Layout({ children }) {
return <body className={inter.className}>{children}</body>;
}
Плюсы:
- Self-hosting — без запросов к Google
- Без layout shift
- Автоматический subset
Локальные:
import localFont from 'next/font/local';
const myFont = localFont({ src: './my-font.woff2' });
Скрипты
import Script from 'next/script';
<Script
src="https://analytics.example.com/script.js"
strategy="afterInteractive"
/>
Стратегии:
beforeInteractive— до интерактиваafterInteractive— после (по умолчанию)lazyOnload— при простоеworker— в web worker
Динамические импорты
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('@/components/Chart'), {
loading: () => <Skeleton />,
ssr: false,
});
Компонент грузится только при использовании.
Анализ бандла
npm install @next/bundle-analyzer
next.config.ts:
import bundleAnalyzer from '@next/bundle-analyzer';
const withBundleAnalyzer = bundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
});
export default withBundleAnalyzer({});
ANALYZE=true npm run build
Package imports
Оптимизация импортов тяжёлых библиотек:
const nextConfig = {
experimental: {
optimizePackageImports: ['lucide-react', '@mui/material'],
},
};
Turbopack
Встроен в Next.js 16. Быстрее Webpack, включён по умолчанию в dev.
Кеширование fetch
fetch(url, { cache: 'force-cache' }); // кеш
fetch(url, { cache: 'no-store' }); // без кеша
fetch(url, { next: { revalidate: 60 } }); // ISR
Static vs Dynamic
- Static — если нет динамики, рендерится на этапе сборки
- Dynamic — если есть
cookies(),headers(),searchParams
Статические страницы быстрее.
Partial Prerendering
Экспериментально. Статическая оболочка + динамические части:
export const experimental_ppr = true;
Итоги
next/image— оптимизация картинокnext/font— шрифты без layout shiftnext/script— контроль загрузкиdynamicдля ленивых компонентов- Анализ бандла
- Кеш
fetchи ISR