Измерение времени сборки в Rollup начинается с понимания того, что сам процесс бандлинга состоит из нескольких фаз, каждая из которых может по-разному влиять на итоговую производительность: загрузка модулей, построение графа зависимостей, трансформация кода через плагины, tree-shaking, генерация выходных чанков и запись файлов на диск. Любая попытка оптимизации без измерений превращается в предположение, поэтому контроль времени сборки становится базовой инженерной практикой при работе с Rollup в проектах среднего и крупного масштаба.
Rollup предоставляет простой способ получить первичную картину
производительности через флаг --perf. При запуске сборки с
этим параметром выводятся детальные тайминги по ключевым этапам
компиляции: создание графа модулей, трансформации, генерация бандла и
запись результата.
Типичный смысл такого вывода заключается не в абсолютных цифрах, а в соотношении этапов. Если большая часть времени уходит в трансформации — проблема обычно в плагинах. Если в генерации — в структуре выходного кода или количестве чанков.
Дополнительно важно учитывать режимы запуска:
rollup -c)rollup -c -w)В watch-режиме --perf показывает первую сборку, но для
повторных изменений уже требуется дополнительное логирование или
кастомные метрики, поскольку incremental-сборка работает иначе и
опирается на кэш.
При использовании программного API Rollup контроль времени становится более гибким. Базовый подход — измерение общего времени выполнения через высокоточные таймеры Node.js:
import { rollup } from 'rollup';
import { performance } from 'node:perf_hooks';
const start = performance.now();
const bundle = await rollup({
input: 'src/index.js'
});
await bundle.write({
file: 'dist/bundle.js',
format: 'esm'
});
const end = performance.now();
console.log(`Build time: ${end - start} ms`);
Такой способ фиксирует только общее время, но уже позволяет сравнивать конфигурации: плагины, уровни минификации, количество входных точек.
Более точный контроль достигается разбиением по этапам:
const t1 = performance.now();
const bundle = await rollup(inputOptions);
const t2 = performance.now();
await bundle.generate(outputOptions);
const t3 = performance.now();
await bundle.write(outputOptions);
const t4 = performance.now();
Это позволяет отделить стоимость генерации от стоимости записи на диск.
Rollup-плагины являются основной причиной нестабильного времени сборки. Каждый плагин может участвовать в разных фазах:
buildStartresolveIdloadtransformgenerateBundleДля измерения влияния конкретного плагина используется ручное профилирование внутри его хуков:
export function timingPlugin() {
return {
name: 'timing-plugin',
transform(code, id) {
const start = performance.now();
// имитация или реальная трансформация
const result = code;
const end = performance.now();
console.log(`transform ${id}: ${end - start} ms`);
return result;
}
};
}
Такой подход быстро выявляет “тяжёлые” модули и точки деградации, особенно при использовании транспайлеров или AST-трансформаций.
Watch-режим принципиально отличается по поведению: Rollup использует кэш графа зависимостей и повторно пересчитывает только изменённые модули. Поэтому измерение времени здесь должно учитывать две метрики:
В практических измерениях часто обнаруживается, что именно первая сборка занимает в 5–20 раз больше времени, особенно при большом количестве зависимостей.
Для логирования изменений в watch-режиме можно использовать хук
watchChange в пользовательской интеграции через API, либо
оборачивать запуск процесса:
let first = true;
watch.on('event', event => {
if (event.code === 'BUNDLE_START') {
start = performance.now();
}
if (event.code === 'BUNDLE_END') {
const end = performance.now();
if (first) {
console.log('Initial build:', end - start);
first = false;
} else {
console.log('Rebuild:', end - start);
}
}
});
Кэш Rollup является ключевым фактором ускорения. При использовании программного API он передаётся явно:
let cache;
const bundle = await rollup({
input: 'src/index.js',
cache
});
cache = bundle.cache;
Измерение времени без кэша и с кэшем даёт объективную картину эффективности оптимизации. Разница особенно заметна при:
transform плагинахRollup сборка концептуально делится на несколько этапов, и каждый имеет разную “цену”:
1. Построение графа модулей Зависит от количества
import и сложности резолвинга. Плагины
resolveId могут сильно увеличивать время.
2. Загрузка модулей Включает файловую систему и виртуальные модули.
3. Трансформация кода Наиболее дорогой этап при использовании Babel, TypeScript или AST-плагинов.
4. Tree-shaking Зависит от структуры модулей и наличия side effects.
5. Генерация бандлов Увеличивается при большом числе чанков.
6. Запись на диск Может стать узким местом при больших sourcemap.
Генерация sourcemap часто недооценивается. При
sourcemap: true Rollup дополнительно строит соответствие
между исходным и итоговым кодом, что может заметно увеличивать время
генерации.
Особенно критично это при:
Измерение обычно показывает, что включение sourcemap может добавлять десятки процентов к времени генерации.
Для глубокой диагностики используется встроенный профилировщик Node.js:
node --inspect node_modules/rollup/dist/bin/rollup -c
Далее через Chrome DevTools можно получить flame graph выполнения, где видно:
Этот метод особенно полезен при нестабильных или “скачущих” временах сборки.
Практический подход к измерению времени сборки заключается в сравнении нескольких конфигураций:
Результаты фиксируются в виде повторяемых запусков, поскольку одиночный прогон не учитывает влияние файлового кэша операционной системы.
В реальных проектах часто создаётся собственная система метрик поверх Rollup API. Она может включать:
Пример агрегированного подхода:
const start = performance.now();
const bundle = await rollup(inputOptions);
const generateStart = performance.now();
const output = await bundle.generate(outputOptions);
const end = performance.now();
return {
modules: bundle.cache?.modules?.length,
generateTime: end - generateStart,
totalTime: end - start
};
Такие данные позволяют отслеживать деградацию сборки при росте проекта.
Измерение времени в Rollup — это не одноразовая операция, а постоянный процесс контроля. Поведение сборки меняется при каждом добавлении плагина, изменении структуры модулей или переходе на другой формат вывода. Без систематического сбора метрик невозможно отличить случайный рост времени от реальной проблемы в архитектуре сборки.