При разработке крупных приложений время запуска dev-сервера и скорость пересборки становятся критически важными факторами. По мере роста количества модулей Parcel вынужден анализировать всё больше файлов, строить граф зависимостей и выполнять преобразования для каждого ресурса. Даже несмотря на высокую производительность Parcel, в больших проектах первоначальная сборка может занимать заметное время.
Для решения этой проблемы в Parcel предусмотрен Lazy mode — режим ленивой компиляции, при котором сборка выполняется только для тех частей приложения, которые реально используются в данный момент.
Обычный режим разработки предполагает следующую последовательность:
Даже если разработчик работает лишь с одной страницей приложения, Parcel всё равно подготавливает весь набор ресурсов, связанных с проектом.
Lazy mode меняет эту стратегию.
Вместо предварительной компиляции всего проекта Parcel:
Такой подход значительно сокращает время запуска dev-сервера.
Предположим, приложение содержит несколько независимых страниц:
src/
├── index.html
├── admin.html
├── profile.html
└── reports.html
При стандартном запуске:
parcel serve src/*.html
Parcel подготовит ресурсы для всех страниц.
В режиме Lazy:
parcel serve src/*.html --lazy
происходит следующее:
index.html.Если затем открыть:
/admin.html
Parcel выполнит отдельную компиляцию только для административной части проекта.
Для запуска используется флаг:
parcel serve src/index.html --lazy
или
parcel src/index.html --lazy
После запуска все бандлы становятся ленивыми по умолчанию.
Рассмотрим последовательность событий.
Запуск сервера:
parcel serve src/index.html --lazy
Открытие страницы в браузере:
http://localhost:1234
В этот момент:
Первый запрос может оказаться немного медленнее обычного, поскольку сборка выполняется непосредственно перед отдачей файла.
Все последующие обращения используют уже готовый результат.
Lazy mode тесно связан с системой кэширования Parcel.
После первой компиляции:
index.js
результат сохраняется в кэше.
Повторный запрос:
index.js
не требует новой сборки.
Если файл изменяется:
console.log("Updated");
Parcel инвалидирует соответствующую часть кэша и выполняет пересборку только изменённых модулей.
Таким образом достигается сочетание:
Наиболее заметный эффект Lazy mode проявляется в проектах с большим количеством entry points.
Например:
src/
├── public/
│ ├── home.html
│ ├── catalog.html
│ ├── contacts.html
│ └── blog.html
│
├── admin/
│ ├── dashboard.html
│ ├── users.html
│ └── reports.html
│
└── account/
├── login.html
└── profile.html
Запуск:
parcel serve "src/**/*.html" --lazy
В обычном режиме Parcel начал бы компиляцию ресурсов для всех страниц.
В Lazy mode:
home.html не вызывает сборку административных
страниц;dashboard.html не затрагивает блог;Для крупных монорепозиториев это может сокращать время старта в несколько раз.
Parcel отлично работает с динамическими импортами.
Пример:
button.addEventListener("click", async () => {
const module = await import("./chart.js");
module.renderChart();
});
Без Lazy mode Parcel заранее подготавливает все необходимые чанки.
С Lazy mode процесс становится ещё более отложенным:
chart.js не компилируется.В результате одновременно работают два механизма оптимизации:
Эти технологии часто путают.
Разделяет приложение на несколько файлов.
Пример:
import("./admin.js");
Результат:
main.js
admin.js
Загрузка происходит по требованию.
Не влияет на структуру бандлов.
Он определяет момент их компиляции.
Даже если чанк уже существует логически в графе зависимостей, Parcel не станет его собирать до реального запроса.
Представим приложение:
5000 модулей
50 страниц
200 динамических чанков
Стандартный режим:
Запуск сервера
↓
Построение графа
↓
Компиляция всех бандлов
↓
Готовность
Lazy mode:
Запуск сервера
↓
Построение графа
↓
Готовность
↓
Компиляция только по запросу
Чем больше проект, тем ощутимее разница.
Предварительная сборка большого количества ресурсов требует хранения:
При использовании Lazy mode количество одновременно обработанных ресурсов уменьшается.
Следствия:
Монорепозитории часто содержат:
apps/
packages/
shared/
tools/
docs/
Приложение может включать десятки независимых веб-интерфейсов.
Например:
parcel serve apps/*/index.html --lazy
При таком подходе разработчик открывает только один сервис:
apps/shop
Parcel не тратит ресурсы на:
apps/admin
apps/docs
apps/analytics
apps/crm
пока они не будут запрошены.
Несмотря на преимущества, существуют особенности, которые необходимо учитывать.
Первая загрузка ресурса включает время компиляции.
Например:
Request
↓
Compile
↓
Response
Из-за этого первая загрузка страницы может оказаться заметно медленнее.
Lazy mode предназначен исключительно для разработки.
Для оценки реальной производительности приложения необходимо использовать production-сборку:
parcel build
или запускать dev-сервер без ленивой компиляции.
Если часть приложения не открывалась во время работы:
/settings
Parcel может никогда не собрать соответствующий код.
Ошибка в этом разделе проявится только после первого обращения.
По этой причине перед релизом необходимо проверять все маршруты приложения.
Lazy mode полностью совместим с Hot Module Replacement.
После первой сборки модуля:
export const version = 1;
изменение файла:
export const version = 2;
вызывает обычный цикл HMR:
Поведение системы горячей замены остаётся прежним.
CRM
ERP
Backoffice
Admin Panel
Сотни страниц редко используются одновременно.
Analytics
Billing
Reports
Support
Marketing
Каждый раздел компилируется независимо.
host
catalog
checkout
profile
payments
Отдельные части системы собираются только по факту обращения.
await import("./editor.js");
await import("./charts.js");
await import("./reports.js");
await import("./pdf.js");
Ленивая компиляция позволяет избежать подготовки редко используемых модулей во время запуска сервера.
Lazy mode особенно эффективен вместе с:
Комбинация этих механизмов позволяет поддерживать высокую скорость разработки даже в приложениях, содержащих тысячи модулей и десятки отдельных бандлов.
Структура проекта:
src/
├── index.html
├── admin.html
├── profile.html
├── index.js
├── admin.js
└── profile.js
Запуск:
parcel serve src/*.html --lazy
Сценарий работы:
Старт сервера
↓
Открытие index.html
↓
Сборка index.js
↓
Работа с главной страницей
↓
Открытие profile.html
↓
Сборка profile.js
↓
Открытие admin.html
↓
Сборка admin.js
Каждая часть приложения компилируется независимо и только тогда, когда действительно становится необходимой. Такой подход значительно ускоряет начало работы над проектом и снижает нагрузку на систему разработки при работе с крупными кодовыми базами.