Настройка автоматичної перевірки розміру бандла в CI/CD
Бандл росте непомітно. Розробник додає залежність, колега імпортує утиліту цілком замість потрібної функції — і через місяць JS-бандл важить на 200 кБ більше, ніж повинен. Перевірка розміру бандла в CI/CD зупиняє це до попадання в прод.
Як це працює
Ідея проста: на кожний PR або деплой збираємо бандл, порівнюємо його розмір (та розмір окремих чанків) з baseline — значеннями з попереднього деплоя або зафіксованими лімітами. Якщо що-то перевищує поріг — CI падає або залишає попередження в PR.
Інструменти діляться на два класи:
| Інструмент | Підхід | Коли використовувати |
|---|---|---|
bundlesize / bundlewatch |
Порівняння з фіксованими лімітами | Простий проекти, швидка настройка |
size-limit (NEAR) |
Лімити + аналіз імпортів | JS-бібліотеки, пакети npm |
| Webpack Bundle Analyzer | Візуалізація, без CI-блокування | Ручний аудит |
Vite rollup-plugin-visualizer |
Те ж для Vite | Ручний аудит |
| Relative CI / BuildBuddy | Порівняння PR vs base branch | Командні проекти, багатий UI |
Настройка через bundlewatch
Встановлюємо:
npm install --save-dev bundlewatch
Конфігурація в package.json:
{
"bundlewatch": {
"files": [
{ "path": "dist/assets/index-*.js", "maxSize": "150kB" },
{ "path": "dist/assets/vendor-*.js", "maxSize": "400kB" },
{ "path": "dist/assets/*.css", "maxSize": "50kB" }
],
"ci": {
"trackBranches": ["main", "master"],
"repoBranchBase": "main"
}
}
}
У GitHub Actions:
name: Bundle Size Check
on: [pull_request]
jobs:
bundlewatch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- run: npx bundlewatch
env:
BUNDLEWATCH_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CI_REPO_OWNER: ${{ github.repository_owner }}
CI_REPO_NAME: ${{ github.event.repository.name }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_BRANCH: ${{ github.head_ref }}
CI_BRANCH_BASE: ${{ github.base_ref }}
bundlewatch залишає коментар в PR з таблицею: поточний розмір, delta, статус.
Настройка через size-limit
size-limit вміє не просто вимірювати, але й аналізувати дерево імпортів — показує, скільки важить конкретний модуль в ізоляції, з урахуванням tree-shaking та gzip.
npm install --save-dev size-limit @size-limit/preset-app
.size-limit.json:
[
{
"path": "dist/assets/index-*.js",
"limit": "150 kB",
"gzip": true
},
{
"name": "Vendor chunk",
"path": "dist/assets/vendor-*.js",
"limit": "380 kB",
"gzip": true
}
]
У package.json:
{
"scripts": {
"size": "size-limit",
"analyze": "size-limit --why"
}
}
--why запускає webpack-bundle-analyzer та показує, що саме тянить розмір.
Відносні лімити замість абсолютних
Абсолютні лімити застарівають — проект росте, і постійно піднімати цифри надоедає. Альтернатива: перевіряти delta відносно base branch.
Скрипт порівняння розмірів в CI:
#!/bin/bash
# Збираємо поточну ветку
npm run build
CURRENT_SIZE=$(du -sb dist/assets/*.js | awk '{sum += $1} END {print sum}')
# Зберігаємо в артефакт
echo $CURRENT_SIZE > /tmp/current_size.txt
# Завантажуємо розмір base branch з артефактів CI
# (логіка залежить від CI системи — тут приклад для GitHub Actions)
BASE_SIZE=$(cat /tmp/base_size.txt 2>/dev/null || echo $CURRENT_SIZE)
DELTA=$((CURRENT_SIZE - BASE_SIZE))
DELTA_PERCENT=$((DELTA * 100 / BASE_SIZE))
echo "Base: ${BASE_SIZE} bytes"
echo "Current: ${CURRENT_SIZE} bytes"
echo "Delta: ${DELTA} bytes (${DELTA_PERCENT}%)"
if [ $DELTA_PERCENT -gt 10 ]; then
echo "ERROR: Bundle grew by more than 10%"
exit 1
fi
Кешування та прискорення
Повна пересборка на кожний PR — повільно. Кешуємо node_modules та результати Vite:
- uses: actions/cache@v4
with:
path: |
node_modules
.vite
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
На типовому проекті це скорочує час перевірки з 3–4 хвилин до 40–60 секунд.
Що перевіряти окрім загального розміру
- Кількість чанків — ріст числа чанків при code splitting може збільшити кількість HTTP-запитів
- Розмір initial bundle окремо від lazy-loaded чанків — саме він впливає на LCP та TTI
- Дублі залежностей — коли одна бібліотека затягується в кілька чанків у різних версіях
Для останнього: npm ls <package> або npx duplicate-package-checker-webpack-plugin.
Сроки внедрення
Базова настройка bundlewatch в існуючий CI-пайплайн — 4–8 годин: встановлення, настройка лімітів під поточні розміри, додавання кроку в workflow. Настройка size-limit з аналізом та сповіщеннями в PR — 1–2 робочих дні з урахуванням тонкої настройки лімітів по чанкам.







