Процесс сборки в Rollup строится вокруг последовательного применения плагинов к каждому модулю. Каждый модуль проходит через цепочку трансформаций, начиная с чтения исходного кода и заканчивая финальной генерацией бандла. Когда количество модулей и плагинов растёт, стоимость этих операций становится критичной, и оптимизация числа трансформаций превращается в один из ключевых факторов производительности сборки.
Внутри Rollup каждый модуль проходит несколько стадий обработки.
Основной этап трансформации реализуется через хук
transform, который вызывается для каждого подключённого
плагина.
Упрощённо процесс выглядит следующим образом:
load)transform)Каждый вызов transform — это потенциально дорогая
операция, особенно если:
Поэтому минимизация количества трансформаций напрямую влияет на скорость сборки.
Rollup использует внутренние механизмы кэширования, позволяющие избежать повторной обработки модулей без изменений. Кэш работает на уровне содержимого и метаданных модуля.
Основные условия, при которых трансформация пропускается:
При соблюдении этих условий Rollup повторно использует уже обработанный результат.
Особенно важно учитывать кэш при watch-режиме, где сборка выполняется многократно. В таких сценариях эффективность кэширования определяет общую отзывчивость системы.
Минимизация трансформаций невозможна без корректной идентификации модулей. Rollup строит граф зависимостей, используя абсолютные пути и внутренние идентификаторы.
Если идентификаторы нестабильны, кэш становится неэффективным. Это происходит в случаях:
Стабильная идентификация позволяет Rollup точно понимать, какой модуль уже был обработан, а какой требует повторной трансформации.
Одним из ключевых механизмов уменьшения количества трансформаций является инкрементальное обновление графа.
При изменении одного файла Rollup:
Это особенно важно в проектах с большим количеством модулей, где полная пересборка каждого файла была бы слишком дорогой.
Инкрементальность опирается на точное отслеживание зависимостей и их изменений. Если зависимость добавляется или удаляется, пересчитывается только ограниченная часть графа.
Каждый плагин, реализующий transform, добавляет
дополнительный слой обработки. В цепочке плагинов порядок имеет
значение, но количество оказывает прямое влияние на
производительность.
Типичные причины избыточных трансформаций:
Оптимизация заключается в сокращении цепочки трансформаций до минимально необходимого набора.
Часть трансформаций можно перенести на этап до Rollup-сборки. Это снижает нагрузку на основной пайплайн.
К таким операциям относятся:
В этом случае Rollup работает уже с готовым JavaScript-кодом, сокращая количество AST-операций.
Некоторые плагины поддерживают условную трансформацию модулей. Это позволяет избегать обработки файлов, которые не требуют изменений.
Пример логики:
node_modules исключается.ts или
.jsxТакая фильтрация снижает количество вызовов transform и
уменьшает нагрузку на сборку.
Rollup позволяет явно исключать файлы или директории из обработки через настройки плагинов и конфигурации.
Наиболее распространённые стратегии:
node_modules из трансформацийinclude и
excludeЧем меньше файлов проходит через трансформационный пайплайн, тем меньше вычислительных затрат.
Некоторые плагины строят AST (абстрактное синтаксическое дерево) для анализа и модификации кода. Повторное построение AST для одного и того же модуля — одна из самых дорогих операций.
Минимизация трансформаций достигается за счёт:
Если модуль не изменился, повторное построение AST полностью исключается.
Каждый последующий плагин в цепочке получает результат предыдущего. Это создаёт линейную зависимость стоимости обработки от количества плагинов.
Глубина цепочки влияет на:
Сокращение цепочки или объединение логики нескольких плагинов в один специализированный слой позволяет уменьшить количество промежуточных преобразований.
Виртуальные модули, создаваемые через плагины, могут увеличивать количество трансформаций, если они генерируются на каждом цикле сборки.
Оптимизация достигается за счёт:
Если виртуальный модуль стабилен, Rollup рассматривает его как обычный кэшируемый модуль.
Watch-режим усиливает важность минимизации трансформаций, так как сборка выполняется многократно при каждом изменении файлов.
Ключевые особенности:
В плохо оптимизированных проектах watch-режим приводит к экспоненциальному росту времени сборки из-за повторной обработки неизменённых модулей.
Один из способов уменьшить количество трансформаций — разделение проекта на несколько независимых сборок.
Каждый контекст имеет:
Это позволяет избежать повторной обработки общих модулей в разных частях системы и локализовать трансформации в пределах отдельного бандла.