Производительность Nuxt
В Nuxt есть встроенные возможности, которые помогают ускорить приложение и улучшить Core Web Vitals. Есть и основные модули ядра Nuxt, которые усиливают производительность в отдельных областях. В этом руководстве собраны рекомендации по оптимизации.
Встроенные возможности
Nuxt предлагает несколько встроенных механизмов оптимизации. Понимание того, как они работают, важно для действительно быстрой работы сайта.
Ссылки
<NuxtLink> заменяет и компонент <RouterLink> из Vue Router, и обычный тег <a>. Он определяет, внутренняя ссылка или внешняя, и рендерит её с доступными оптимизациями (предзагрузка, атрибуты по умолчанию и т.д.).
<template>
<NuxtLink to="/about">Страница «О нас»</NuxtLink>
</template>
<!-- в разметке: Vue Router и умная предзагрузка -->
<a href="/about">Страница «О нас»</a>
Nuxt по умолчанию включает умную предзагрузку: когда ссылка становится видимой (по умолчанию — в области просмотра или при прокрутке), подгружается JavaScript целевых страниц, чтобы к клику они уже были готовы.
Можно переключиться на предзагрузку по взаимодействию:
export default defineNuxtConfig({
experimental: {
defaults: {
nuxtLink: {
prefetchOn: 'interaction',
},
},
},
})
Гибридный рендеринг
В сложных приложениях часто нужен полный контроль над тем, как страницы отдаются: одни — сгенерированы при сборке, другие — только на клиенте.
Гибридный рендеринг задаёт разные правила кэширования для маршрутов через опцию routeRules в конфигурации (правила маршрутизации, route rules) и определяет, как сервер отвечает на запрос по URL:
export default defineNuxtConfig({
routeRules: {
'/': {
prerender: true,
},
'/products/**': {
swr: 3600,
},
'/blog': {
isr: 3600,
},
'/admin/**': {
ssr: false,
},
},
})
Сервер Nuxt автоматически регистрирует соответствующие middleware и оборачивает маршруты обработчиками кэша на уровне Nitro.
Ленивая загрузка компонентов
Чтобы подключить компонент динамически (ленивую загрузку), добавьте префикс Lazy к имени компонента. Это удобно, если компонент нужен не всегда.
<script setup lang="ts">
const show = ref(false)
</script>
<template>
<div>
<h1>Горы</h1>
<LazyMountainsList v-if="show" />
<button v-if="!show" @click="show = true">Показать список</button>
</div>
</template>
Префикс Lazy откладывает загрузку кода компонента до нужного момента и помогает уменьшить размер JS-бандла.
Отложенная гидратация
Не всем компонентам нужна гидратация (интерактивность) сразу при первой загрузке. С отложенной гидратацией вы контролируете, когда подгружается код компонентов — это улучшает метрику «время до интерактивности» (time to interactive). В Nuxt можно задать момент, когда компоненты становятся интерактивными (начиная с Nuxt v3.16).
<template>
<div>
<LazyMyComponent hydrate-on-visible />
</div>
</template>
Часто имеет смысл откладывать гидратацию до появления в области просмотра или до завершения более приоритетных задач браузера.
Получение данных
Чтобы не запрашивать одни и те же данные дважды (на сервере и на клиенте), в Nuxt есть useFetch и useAsyncData. Если запрос выполнен на сервере, данные передаются клиенту в payload, без повторного запроса.
Основные модули Nuxt
Помимо встроенных возможностей, команда Nuxt поддерживает модули, которые дополнительно ускоряют приложение: изображения, шрифты, сторонние скрипты.
Изображения
Неоптимизированные изображения сильно бьют по производительности, в том числе по Largest Contentful Paint (LCP).
В Nuxt можно использовать модуль Nuxt Image — готовую оптимизацию картинок. Он меняет размер и формат через встроенный оптимизатор или CDN.
<NuxtImg> заменяет обычный <img> и добавляет:
- встроенный провайдер для локальных и удалённых изображений;
- преобразование
srcв URL с современными форматами (WebP, Avif); - автоматический ресайз по
widthиheight; - адаптивные
sizesпри указании опции sizes; - нативная ленивая загрузка (
lazy loading) и остальные атрибуты<img>.
Картинки обычно делят на важные для первого экрана (LCP) и те, что можно подгрузить позже:
<template>
<!-- 🚨 загрузить как можно раньше -->
<NuxtImg
src="/hero-banner.jpg"
format="webp"
preload
loading="eager"
fetch-priority="high"
width="200"
height="100"
/>
<!-- 🐌 можно загрузить позже -->
<NuxtImg
src="/facebook-logo.jpg"
format="webp"
loading="lazy"
fetch-priority="low"
width="200"
height="100"
/>
</template>
Шрифты
Nuxt Fonts автоматически оптимизирует шрифты (включая кастомные) и убирает лишние внешние запросы — лучше и приватность, и скорость.
Встроено автоматическое размещение файлов шрифтов на своём хосте (self-hosting): веб-шрифты загружаются предсказуемее, с меньшим сдвигом вёрстки за счёт пакета fontaine.
Nuxt Fonts обрабатывает CSS и при объявлении font-family автоматически:
- Находит шрифты — сначала в
public/, затем у провайдеров (Google, Bunny, Fontshare и др.). - Генерирует правила @font-face — подставляет CSS для загрузки из нужных источников.
- Проксирует и кэширует — переписывает URL на
/_fonts, скачивает и кэширует локально. - Задаёт метрики fallback — подгоняет системные шрифты под веб-шрифты, снижая CLS (CLS).
- Включает шрифты в сборку — хэширует имена файлов и выставляет долгоживущие заголовки кэша.
Провайдеры вынесены в расширяемую архитектуру: можно взять готовый или написать свой.
Скрипты
Сторонние ресурсы — аналитика, видео, карты, соцсети — расширяют функциональность, но часто ухудшают UX и бьют по INP и LCP.
Nuxt Scripts помогает подключать сторонние скрипты с упором на производительность, приватность, безопасность и удобство разработки.
Nuxt Scripts даёт слой абстракции над сторонними скриптами: SSR, типобезопасность и при этом полный низкоуровневый контроль над загрузкой.
const { onLoaded, proxy } = useScriptGoogleAnalytics(
{
id: 'G-1234567',
scriptOptions: {
trigger: 'manual',
},
},
)
// события в очереди до загрузки GA
proxy.gtag('config', 'UA-123456789-1')
// или дождаться загрузки скрипта
onLoaded((gtag) => {
// скрипт загружен
})
Инструменты профилирования
Чтобы ускорять приложение, сначала нужно измерять: в разработке на локальной машине и затем на продакшене.
Nuxi Analyze
Команда nuxi анализирует продакшен-бандл Nuxt-приложения. Используется vite-bundle-visualizer (аналог webpack-bundle-analyzer) и строится наглядная карта бандла — видно, что занимает больше всего места.
Крупный блок в визуализации часто сигнализирует, что пора оптимизировать: разбить на части, подключить ленивую загрузку или заменить зависимость, особенно если это тяжёлая сторонняя библиотека.
Блоки из множества мелких элементов иногда уменьшают, импортируя только нужное вместо целых модулей; крупные автономные блоки чаще выносят в ленивую загрузку вместо основного бандла.
Nuxt DevTools
Nuxt DevTools даёт прозрачность по приложению: где узкие места по производительности и как устроена конфигурация.

Среди возможностей для замеров:
- Временная шкала (Timeline) — время рендера, обновлений и инициализации компонентов, поиск узких мест.
- Ресурсы (Assets) — размеры файлов (например изображений) без преобразований.
- Дерево рендера (Render Tree) — связи между компонентами Vue, скриптами и стилями для оптимизации динамической загрузки.
- Просмотр (Inspect) — список файлов приложения с размером и временем оценки.
Chrome DevTools
В Chrome DevTools удобны вкладки «Производительность» (Performance) и отчёт Lighthouse.
В панели Performance сразу видны локальные оценки LCP и CLS (хорошо / нужно улучшить / плохо).
При взаимодействии со страницей фиксируется INP — полная картина Core Web Vitals для вашего устройства и сети.

Lighthouse проверяет производительность, доступность, SEO, PWA и соответствие рекомендациям, формирует отчёт. Проваленные проверки — ориентир, что править.

У каждой проверки есть справка: зачем она и как исправить.
PageSpeed Insights
PageSpeed Insights (PSI) отражает опыт пользователей на мобильных и десктопе и даёт рекомендации по улучшению страницы.
Есть лабораторные данные (удобно для отладки в контролируемой среде) и полевые (реальный опыт пользователей).
WebPageTest
WebPageTest — инструмент с глубокой диагностикой: как страница ведёт себя в разных условиях.
Тесты можно гонять из разных точек мира, в реальных браузерах и с настраиваемыми параметрами сети.
Типичные проблемы
В крупных приложениях на Nuxt часто встречаются задачи ниже. Разобравшись с ними, вы ускорите сайт.
Избыточное использование плагинов
Проблема: много плагинов, особенно тяжёлых при инициализации, бьёт по производительности. Плагины выполняются в фазе гидратации — плохая настройка блокирует рендер и портит UX.
Решение: пересмотреть плагины; часть логики лучше вынести в композабл или утилиту.
Мёртвый код и зависимости
Проблема: со временем накапливаются неиспользуемый код и пакеты. Они раздувают бандл, хотя не нужны в рантайме.
Решение: проверить package.json и код на неиспользуемые зависимости, утилиты, композаблы и функции.
Игнорирование советов Vue по производительности
Проблема: в документации Vue есть приёмы, которые подходят и для Nuxt, но их забывают, сфокусировавшись только на особенностях Nuxt, хотя приложение остаётся Vue-проектом.
Решение: использовать shallowRef, v-memo, v-once и другие рекомендации Vue.
Отсутствие единых паттернов
Проблема: чем больше людей в проекте, тем сложнее поддерживать кодовую базу. Подтягивание чужих паттернов без согласования даёт конфликты и проблемы с производительностью.
Решение: зафиксировать правила и паттерны, например хорошие практики и паттерны для Vue-композаблов.
Попытка загрузить всё сразу
Проблема: если не задан порядок загрузки, страница тянет ресурсы параллельно «всё и сразу» — медленно и неудобно пользователю.
Решение: опираться на progressive enhancement: сначала основной контент, затем слои оформления и функций по мере возможностей браузера и сети.
Полезные материалы
Дополнительно о приёмах ускорения: