NuxtMiddleTechnical

Как Nuxt управляет code splitting и lazy loading компонентов?

Nuxt автоматически делит бандл по маршрутам (pages/), а компоненты можно загружать лениво через префикс Lazy или defineAsyncComponent. Анализ чанков — npx nuxi analyze.

Code Splitting и Lazy Loading в Nuxt

Nuxt использует Vite (или webpack) в качестве бандлера и автоматически разбивает приложение на чанки. Каждый маршрут получает свой отдельный чанк, который загружается только при переходе пользователя на соответствующую страницу.

Автоматический code splitting по маршрутам

Все файлы в директории pages/ автоматически становятся отдельными чанками. Nuxt не требует явной конфигурации — разбивка по маршрутам включена по умолчанию.

Lazy-компоненты через префикс Lazy

Любой компонент из components/ можно загрузить лениво, добавив префикс Lazy к имени тега:

// components/HeavyChart.vue — существует в проекте

// pages/dashboard.vue
<template>
  <div>
    <!-- Компонент загрузится только при монтировании -->
    <LazyHeavyChart v-if="showChart" :data="chartData" />
    <button @click="showChart = true">Показать график</button>
  </div>
</template>

<script setup lang="ts">
const showChart = ref(false)
const chartData = ref([])
</script>

defineAsyncComponent для ручного контроля

// Явный lazy import с fallback и обработкой ошибок
const HeavyComponent = defineAsyncComponent({
  loader: () => import('~/components/HeavyChart.vue'),
  loadingComponent: LoadingSpinner,
  errorComponent: ErrorFallback,
  delay: 200,       // ms перед показом loadingComponent
  timeout: 5000,    // ms до показа errorComponent
})

Экспериментальный Payload Extraction

В Nuxt 3.x доступен флаг payloadExtraction, который выносит данные страниц в отдельные JSON-файлы при статической генерации:

// nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    payloadExtraction: true,
  },
})

Анализ бандла

# Запустить анализатор размера чанков
npx nuxi analyze

Команда открывает визуальный отчёт (rollup-plugin-visualizer), где видно, какие модули попали в какой чанк и почему.

Prefetch и Preload

Nuxt автоматически добавляет <link rel="prefetch"> для маршрутов, видимых в viewport через <NuxtLink>. Можно управлять этим поведением:

// nuxt.config.ts
export default defineNuxtConfig({
  router: {
    options: {
      linkActiveClass: 'active',
    },
  },
  experimental: {
    crossOriginPrefetch: true,
  },
})

Подводные камни

  • Префикс Lazy создаёт отдельный чанк только если компонент не используется нигде в eager-режиме — если тот же компонент импортирован без Lazy в другом месте, чанк всё равно будет в основном бандле.
  • Слишком мелкая нарезка: сотни крохотных чанков по 1–2 KB хуже одного чанка из-за накладных расходов HTTP/1.1; с HTTP/2 граница сдвигается, но всё равно важно не дробить без смысла.
  • Hydration mismatch при использовании LazyComponent с SSR: если компонент рендерится на сервере, добавьте <ClientOnly> или используйте v-if с правильной логикой.
  • defineAsyncComponent и авто-импорт несовместимы: нельзя написать const C = defineAsyncComponent(...) и ожидать, что Nuxt подхватит его как авто-импорт.
  • Динамические импорты с переменными (import(`./${name}.vue`)) создают wildcard-чанки и ломают tree-shaking — всегда используйте статические строки.
  • При ssr: false весь SPA грузится одним entry-point — code splitting по маршрутам всё равно работает, но первый бандл больше из-за отсутствия серверного рендеринга.
  • Vite chunking strategy по умолчанию может объединять модули неожиданным образом; для контроля нужен build.rollupOptions.output.manualChunks в nuxt.config.

Common mistakes

  • Путать code splitting and lazy loading с похожим API из соседнего фреймворка.
  • Не объяснять, где код выполняется: сервер, клиент, build step или runtime.
  • Игнорировать влияние на hydration, cache, bundle size или безопасность.

What the interviewer is testing

  • Точно объясняет назначение механизма «code splitting and lazy loading».
  • Показывает корректный минимальный пример без выдуманных API.
  • Называет ограничения, failure modes и production-компромиссы.

Sources

Related topics