Розмір JavaScript безпосередньо впливає на час, коли сторінка стає інтерактивною: файл треба завантажити, розібрати й виконати, а на слабких телефонах останні два кроки займають більше часу, ніж мережа.
Що Vue робить сам:
- компіляція шаблонів заздалегідь: з Vite шаблони
.vue-файлів компілюються під час збирання, тому в бандл іде runtime-збірка Vue без компілятора шаблонів (приблизно на третину менша). Компілятор потрібен лише якщо шаблони задаються рядками під час виконання - цього варто уникати; - tree shaking API: якщо не використовується
<Transition>чи<KeepAlive>, їхнього коду не буде в бандлі.
Що робити вам:
1. Подивитися, що всередині. rollup-plugin-visualizer показує розмір кожного модуля. Майже завжди знаходяться сюрпризи: уся бібліотека іконок через один імпорт, повна локалізація бібліотеки дат, дві версії однієї залежності.
2. Імпортувати точково:
import { debounce } from 'lodash-es' // замість import _ from 'lodash'
import CalendarIcon from '~icons/heroicons/calendar' // одна іконка, а не набір
3. Обирати залежності з думкою про розмір - перевірити розмір пакета до встановлення (bundlephobia, pkg-size). Інколи 20 рядків власного коду кращі за бібліотеку на 50 КБ.
4. Розділяти код - ліниві маршрути й асинхронні компоненти для рідко потрібного.
5. Бібліотеки компонентів - підключати компоненти за потреби (автоімпорт unplugin-vue-components), а не реєструвати всю бібліотеку глобально.
6. Пакети у форматі ES-модулів - для них працює tree shaking; пакети CommonJS потрапляють цілими.
Метрики й контроль:
- розмір після стиснення (gzip/brotli) - те, що реально йде мережею;
- бюджет розміру в CI (
size-limitчи перевірка звіту збирання) - щоб регресії ловилися в пул-реквесті, а не через пів року; - Lighthouse і реальні метрики (INP, LCP) - кінцевий критерій, а не кілобайти самі по собі.
Для Laravel + Inertia: сторінки, підключені через import.meta.glob з { eager: true }, потрапляють у головний бандл усі разом - для великих застосунків краще ліниве завантаження сторінок.