Асинхронные компоненты и lazy loading
↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая
Зачем это на собесе
Как уменьшить начальный бандл: код-сплиттинг компонентов и маршрутов.
Объяснение
import { defineAsyncComponent } from "vue";
const HeavyChart = defineAsyncComponent(() => import("./HeavyChart.vue"));
const AsyncModal = defineAsyncComponent({
loader: () => import("./Modal.vue"),
loadingComponent: Spinner,
errorComponent: ErrorBlock,
delay: 200, // не показывать loading сразу
timeout: 10_000,
hydrate: hydrateOnVisible(), // 3.5: ленивая гидратация (SSR)
});// Маршруты: динамический import — отдельный чанк на страницу
const routes = [{ path: "/reports", component: () => import("@/pages/ReportsPage.vue") }];Стратегии:
| Что | Как |
|---|---|
| Маршруты | () => import(...) (по умолчанию для всех страниц) |
| Тяжёлые компоненты | defineAsyncComponent (графики, редакторы, PDF) |
| Показ по условию | v-if + async-компонент — грузится при первом показе |
| Предзагрузка | import() на hover/idle, <link rel="prefetch"> (/* webpackPrefetch: true */, Vite: modulepreload) |
| Тяжёлые библиотеки | динамический import("lib") внутри обработчика |
| Ленивая гидратация | hydrateOnVisible, hydrateOnIdle (SSR) |
Vite создаёт отдельные чанки по динамическим импортам; manualChunks группирует библиотеки (vendor).
Индикация загрузки: Suspense или loadingComponent, скелетоны; обработка ошибок загрузки чанка (обновление приложения: vite:preloadError → перезагрузка).
Нюансы и подводные камни
- Слишком мелкие чанки увеличивают число запросов; слишком крупные — задержку.
- После деплоя старые чанки исчезают: пользователи со старой вкладкой получают ошибку загрузки — обработайте.
- Асинхронные компоненты внутри
KeepAlive/Suspenseтребуют аккуратности. - Проверяйте состав бандла (
rollup-plugin-visualizer).
Практика
- Сделайте маршруты ленивыми и посмотрите чанки в build.
- Загрузите график только при открытии вкладки.
- Настройте предзагрузку следующей страницы при наведении.
Вопросы с ответами
Как уменьшить начальный бандл?
Ленивые маршруты и тяжёлые компоненты (
import()), разделение vendor-чанков, удаление неиспользуемого кода.
Что делать при ошибке загрузки чанка после деплоя?
Обработать
vite:preloadError/ошибку импорта и предложить перезагрузку.