Шрифты, статика и производительность
Подключаем шрифты без мерцания, кладём статику в public/ и разбираемся, что делает сайт быстрым.
next/fontподключает и самохостит шрифты на этапе сборки, убирая внешний запрос и «мерцание» текста, а скорость сайта в целом измеряют метриками Core Web Vitals.
Шрифты через next/font
Если подключить шрифт ссылкой на Google Fonts, браузер делает запрос к стороннему домену, и пока шрифт грузится, текст мигает. next/font убирает и лишний запрос, и мерцание — шрифт скачивается при сборке и раздаётся с вашего домена:
// app/layout.tsx
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin", "cyrillic"] });
export default function RootLayout({ children }) {
return (
<html lang="ru" className={inter.className}>
<body>{children}</body>
</html>
);
}
Свой файл шрифта подключают через next/font/local — принцип тот же.
Статические ресурсы
Файлы из public/ отдаются от корня сайта. Туда кладут favicon, robots.txt и картинки, которые не нужно оптимизировать:
| Файл | URL |
public/robots.txt | /robots.txt |
public/og-image.png | /og-image.png |
Core Web Vitals
Скорость сайта измеряют тремя метриками Google:
| Метрика | Что измеряет |
| LCP | Время появления крупного контента |
| INP | Скорость отклика на действия пользователя |
| CLS | Стабильность вёрстки — насколько элементы «прыгают» |
Многие оптимизации Next.js включены по умолчанию и улучшают эти метрики: серверные компоненты (меньше JS → лучше INP), SSG/ISR (готовый HTML → LCP), next/image (лёгкие картинки → LCP и CLS), next/font (нет мерцания → CLS).
Разделение кода
Next.js не отдаёт один гигантский бандл: код бьётся по маршрутам, и пользователь качает только нужное текущей странице. Прикинем выгоду:
const totalKb = 600; // весь код приложения
const routes = 10; // страниц
const perRoute = Math.round(totalKb / routes);
console.log("Без разделения грузим, КБ:", totalKb);
console.log("С разделением на страницу, КБ:", perRoute);
Вывод:
Без разделения грузим, КБ: 600 С разделением на страницу, КБ: 60
Тяжёлый клиентский компонент можно ещё и подгружать лениво через dynamic, чтобы он не утяжелял первый экран:
import dynamic from "next/dynamic";
const HeavyEditor = dynamic(() => import("./HeavyEditor"));
export default function Page() {
return <HeavyEditor />;
}
Метрики смотрят в Lighthouse и в отчёте next build; правило — сначала измеряем, потом оптимизируем узкое место.
Итог
next/fontсамохостит шрифты (нет внешнего запроса и мерцания); статику кладут вpublic/.- Core Web Vitals (LCP, INP, CLS) — измеримая скорость; серверные компоненты,
next/imageиnext/fontулучшают их по умолчанию. - Код делится по маршрутам, тяжёлые куски грузят лениво через
dynamic.