Современные сборщики модулей стремятся не только оптимизировать
процесс сборки, но и управлять поведением загрузки кода в браузере. В
Vite эти задачи решаются через тонкую интеграцию с динамическими
импортами и автоматическую генерацию подсказок для браузера в виде
prefetch и preload директив. Эти механизмы
позволяют управлять приоритетами загрузки чанков, снижать время до
интерактивности и перераспределять сетевые ресурсы более предсказуемым
образом.
Vite опирается на нативные ES-модули и динамический импорт:
const module = await import('./feature.js')
Каждый динамический импорт становится отдельным чанком. По умолчанию браузер загружает такие чанки только тогда, когда код действительно выполняется. Это создаёт ленивую модель загрузки, но не даёт возможности заранее подготовить ресурсы.
Для управления этим поведением Vite добавляет механизм подсказок загрузки через специальные атрибуты ссылок, которые внедряются в HTML или через runtime-обвязки.
preload обозначает ресурс, который необходим в
ближайшем будущем и критичен для текущего рендеринга
страницы.
Характеристики:
Пример HTML-механизма:
<link rel="preload" href="/assets/feature.js" as="script">
prefetch используется для ресурсов, которые
могут понадобиться в будущем, но не являются критичными для
текущего состояния страницы.
Характеристики:
Пример:
<link rel="prefetch" href="/assets/feature.js" as="script">
Vite анализирует граф зависимостей и динамические импорты, после чего
решает, какие чанки стоит предварительно загрузить. Основной механизм
работает через Rollup-плагин @vitejs/plugin-vue или
встроенную оптимизацию HTML.
Vite автоматически добавляет preload для модулей,
которые:
Пример поведения:
import Header from './components/Header.vue'
Такой модуль попадёт в основной бандл или будет помечен как критический чанк, если происходит код-сплиттинг.
Динамические импорты:
const openModal = async () => {
const module = await import('./Modal.vue')
}
Vite рассматривает их как кандидатов для prefetch, так
как они:
При сборке Vite может генерировать:
<link rel="prefetch" href="/assets/Modal.js">
В основе Vite лежит Rollup, который строит статический граф зависимостей. Каждый узел графа имеет метаданные:
На основе этих данных формируется стратегия загрузки:
preload.prefetch.Vite внедряет preload/prefetch через HTML-transform плагин. При
обработке index.html выполняется анализ тегов
<script type="module">.
Пример исходного HTML:
<script type="module" src="/src/main.js"></script>
После обработки Vite может добавить:
<link rel="modulepreload" href="/assets/vendor.js">
<link rel="modulepreload" href="/assets/main.js">
modulepreload является более специализированной формой
preload, предназначенной для ES-модулей.
В контексте Vite чаще используется именно
modulepreload.
Особенности:
Пример:
<link rel="modulepreload" href="/assets/app.js">
В приложениях с роутингом (например, Vue Router или React Router) Vite не знает заранее, какой маршрут будет активен. Поэтому:
preload;prefetch;Пример:
const Home = () => import('./pages/Home.vue')
const About = () => import('./pages/About.vue')
Результат сборки обычно включает:
Браузерная модель приоритизации взаимодействует с директивами следующим образом:
Vite использует эту модель для балансировки:
Некорректная конфигурация может приводить к повторной загрузке одного и того же модуля:
Современные браузеры частично оптимизируют это через deduplication, но Vite старается минимизировать такие ситуации на этапе сборки.
prefetch и preload не только влияют на приоритет загрузки, но и на поведение кеша:
Особенно заметен эффект в SPA с большим количеством ленивых маршрутов.
В SSR-сценариях Vite дополнительно синхронизирует:
Это позволяет:
Упрощённо стратегия выглядит так:
Использование preload и prefetch в Vite напрямую влияет на ключевые метрики:
Модель загрузки становится предсказуемой за счёт разделения критических и некритических чанков на уровне сборки, а не runtime.