tgoop.com/super_oleg_dev/119
Last Update:
Привет!
Сейчас у Next.js проходит эпик по ускорению development сборки - очень уж сильно жалуются пользователи на перф при использовании новой app directory.
Периодически ищу что-то интересное в issues некста, так как тоже используем webpack и swc, и в этом квартале тоже работаем над ускорением сборки.
Пример постов, где можно найти какие-то интересные PR или ссылочки:
- https://github.com/vercel/next.js/issues/48748#issue-1680013792
- https://github.com/vercel/next.js/issues/49929#issuecomment-1637185156
- из последнего issue сразу же неплохая вводная статья про GC и утечки в Node.js - https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/
Всю эту историю я начал смотреть после профилирования `tramvai start` на одном из наших приложений (одно из самых больших, очень много модулей), где повторная сборка с прогретым webpack file-system cache занимала очень много времени (до минуты на m1, полторы-две минуты на intel). Вот парочкой наших проблем и решений, где малыми усилиями получили хорошие результаты, хочу поделиться.
Профилировка показала что примерно 60-70% времени занимает работа либы `watchpack`, которая отвечает в вебпаке за отслеживание изменений файлов и папок.
Оказалось, проблема специфичная для MacOS, где проблему вызывает закрытие огромного количества watchers. Кардинальное уменьшение решает проблему и при этом я не заметил никакого замедления реакции на изменение файлов.
Как уменьшить количество watchers - env переменная `WATCHPACK_WATCHER_LIMIT=20`
Issues по теме:
- https://github.com/webpack/watchpack/issues/222
- https://github.com/vercel/next.js/pull/51826
Второй кейс - потребление памяти.
На этом же приложении development сборки занимала минимум 12 GB оперативной памяти.
При этом для production сборки коллеги не увеличивали `max_old_space_size`
, то есть проблема только во время работы dev сервера.
У трамвая изначально есть такая особенность, что в development режиме отключена опция splitChunks, которая отвечает за эффективное разделение кода, и в 5 вебпаке по дефолту уже давно используется отличная стратегия granular chunking.
Выключено как я понимаю по двум причинам:
- в теории может замедлять dev сборку на время работы плагина
- появляется куча рандомных чанков что усложняет тестирование и разработку
- так сделано в Next.js, главный референс при интеграции granular chunking стратегии разделения кода
У меня уже пару недель в голове крутилась мысль, что не используя splitChunks в приложениях с огромным количеством динамических импортов (обычно на каждый роут), мы дублируем все их общие зависимости в каждом чанке страницы.
Ок, включил splitChunks, поправил упавшие тесты, проверили на приложении:
- потребление памяти снизилось с 12 gb до менее чем 3 gb 🚀
- повторная сборка с прогретыми кэшами ускорилась в несколько раз (на m1 примерно с 45 секунд до 10) - оказалось что размер FS кэшей клиентской сборки тоже уменьшился с нескольких гигабайт до сотен мегабайт
- холодный старт ускорился незначительно
То есть теория полностью подтвердилась, оптимизация радикально уменьшает потребление памяти за счет удаления огромного количества дубликатов модулей.
Кстати пытаюсь в issues некста достучаться до мейнтейнеров, что бы аналогично попробовали включить splitChunks в dev режиме - https://github.com/vercel/next.js/issues/49929#issuecomment-1647549143
Вот такие небольшие истории успеха, надеюсь будет полезно для ваших development сборок.
А в следующем посте план рассказать про многочисленные факапы за последнее время)
BY SuperOleg dev notes

Share with your friend now:
tgoop.com/super_oleg_dev/119