Что такое чанки в WEB

Чанки (chunks) в вебе - это части JavaScript, CSS и других ресурсов, на которые приложение автоматически разбивается при сборке.
Вместо загрузки всего кода приложения одним большим файлом браузер получает только те части, которые нужны пользователю в данный момент.
Например:
  • главная страница → грузится main.chunk.js
  • страница профиля → отдельно profile.chunk.js
  • админка → admin.chunk.js
Это нужно, чтобы:
  • ускорить первую загрузку;
  • не тащить пользователю код, который ему пока не нужен;
  • уменьшить трафик и нагрузку.

Как было раньше

Раньше фронтенд часто собирался в один огромный JavaScript-файл app.js = 15 MB
Внутри него находилось практически всё приложение:
  • главная страница;
  • профиль;
  • корзина;
  • админка;
  • чат;
  • графики;
  • настройки;
  • библиотеки;
  • формы;
  • модалки;
  • аналитика.
Когда пользователь открывал сайт, браузер сначала скачивал HTML-страницу, внутри которой находилась ссылка на основной JavaScript-файл, например app.js. После этого браузер начинал загружать этот файл целиком, даже если в нем находился код для всех страниц и функций приложения. Если размер такого файла был большим, например 15 MB, загрузка могла занимать заметное время, особенно на мобильном интернете или слабых устройствах. Но на скачивании всё не заканчивалось: браузеру нужно было распарсить JavaScript-код, подготовить его к выполнению и выполнить. Только после этого приложение становилось интерактивным - начинали работать кнопки, формы, переходы между страницами и другая логика сайта. Из-за этого пользователь мог наблюдать такую ситуацию, когда страница визуально уже открылась, но интерфейс ещё не реагирует на действия.

Что такое подгрузка чанков

Подгрузка чанков - это такой механизм ленивой загрузки (lazy loading - подход, при котором данные или ресурсы загружаются не заранее, а только в момент, когда они действительно понадобились пользователю) и разделения кода (code splitting), при котором браузер не загружает весь JavaScript приложения сразу. Вместо этого код приложения разбивается на отдельные части - чанки, которые подгружаются только в момент необходимости.
Например, дополнительный JavaScript может быть загружен при переходе пользователя на новую страницу, открытии модального окна, нажатии кнопки или появлении определенного блока на экране. В такой момент браузер выполняет дополнительный HTTP-запрос, например GET /assets/profile.chunk.js, скачивает нужный chunk и только после этого выполняет соответствующий код. Такой подход позволяет уменьшить объем первоначальной загрузки приложения, ускорить отображение интерфейса и снизить нагрузку на устройство пользователя.

Какие бывают чанки

Чанки можно разделять по разным принципам: по страницам, по функциональности, по внешним библиотекам или по типу ресурса. Это делается для того, чтобы приложение загружало только действительно нужный код, а не весь фронтенд сразу.

Route chunks

Route chunks - это чанки, которые создаются для отдельных страниц или маршрутов приложения.

Например:
/home
/profile
/settings

Для каждой страницы может быть создан отдельный JavaScript-файл:
home.chunk.js
profile.chunk.js
settings.chunk.js
Когда пользователь открывает главную страницу, браузер загружает код главной страницы. Если пользователь позже переходит в профиль, браузер дополнительно загружает profile.chunk.js. Такой подход часто используется в одностраничных приложениях, где разные разделы сайта могут иметь разную логику и интерфейс.
Это один из самых распространённых вариантов разделения кода, потому что пользователь обычно не работает со всеми страницами приложения сразу.

Vendor chunks

Vendor chunks - это чанки, в которые выносятся внешние библиотеки и зависимости приложения.
Например:
react
lodash
moment
axios
chart.js
Такие библиотеки часто не относятся к конкретной странице, а используются в разных частях приложения. Поэтому их удобно вынести в отдельный файл, например: vendor.chunk.js
Главная причина - кэширование. Код приложения может меняться часто, а внешние библиотеки обычно обновляются реже. Если vendor.chunk.js уже был загружен пользователем раньше, браузер может взять его из кэша и не скачивать заново при следующем открытии сайта.
Например, если разработчики поменяли текст кнопки на странице профиля, может измениться только profile.chunk.js, а vendor.chunk.js останется прежним.

Feature chunks

Feature chunks - это чанки, которые создаются для отдельных функций или крупных возможностей приложения.
Например:
chat.chunk.js
payment.chunk.js
editor.chunk.js
Такой подход полезен, когда какая-то функция нужна не всем пользователям и не сразу.
Например, онлайн-чат может быть доступен на сайте, но пользователь может вообще его не открыть. В этом случае нет смысла загружать код чата при первом открытии страницы. Лучше загрузить chat.chunk.js только тогда, когда пользователь нажал на кнопку «Открыть чат».
То же самое может быть с оплатой, редактором изображений, картой, графиками, видеоплеером или сложной формой.

CSS chunks

CSS chunks - это отдельные файлы со стилями, которые тоже могут разделяться по страницам или компонентам.
Например:
styles.chunk.css
profile.chunk.css
admin.chunk.css
Это нужно для того, чтобы браузер не загружал все стили приложения сразу. Если пользователь не открывал админку, ему не обязательно загружать стили для таблиц, графиков и административных форм.
CSS chunks часто создаются вместе с JavaScript chunks. Например, при открытии страницы профиля браузер может загрузить не только profile.chunk.js, но и profile.chunk.css.
В результате пользователь получает только те стили и код, которые нужны для текущего экрана.

Как браузер понимает, какие чанки нужно загружать

Когда приложение собирается с помощью таких инструментов, как Webpack или Vite, сборщик не просто создает JavaScript-файлы. Вместе с чанками он формирует дополнительную служебную информацию, которая помогает браузеру понимать:
  • какие части приложения существуют;
  • какие файлы связаны между собой;
  • какой chunk нужно загрузить в конкретный момент времени.
Для этого обычно создаются:
  • manifest;
  • карта зависимостей;
  • runtime-код.

Manifest

Manifest - это специальное описание собранных файлов приложения.
В нем хранится информация:
  • какие чанки существуют;
  • как они называются;
  • где лежат;
  • какие хеши имеют.
Например, после сборки файл может называться не просто profile.chunk.js, а profile.a81f3.js.
Manifest помогает приложению понять: «Если нужен chunk профиля - загружай файл profile.a81f3.js».
Это особенно важно из-за кэширования и постоянных релизов, потому что имена файлов после каждой сборки могут меняться.

Карта зависимостей

Во время сборки сборщик анализирует зависимости приложения.

Например:
  • страница профиля использует React;
  • компонент графика использует chart.js;
  • чат использует websocket-клиент.

Сборщик строит карту зависимостей: какой код зависит от какого.
Благодаря этому runtime понимает:
  • какие чанки нужно загрузить вместе;
  • в каком порядке их подключать;
  • какие библиотеки уже есть в памяти браузера.
Например, profile.chunk.js может зависеть от vendor.chunk.js.
Тогда браузер сначала убедится, что загружен vendor chunk, и только потом выполнит код профиля.

Runtime

Runtime - это небольшой служебный JavaScript-код, который управляет загрузкой чанков во время работы приложения.
В HTML может подключаться файл <script src="runtime.js"></script>
Runtime отвечает за динамическую загрузку кода и знает:
  • какой chunk нужен;
  • где находится файл;
  • загружен ли он уже;
  • нужно ли скачивать его повторно;
  • когда начинать загрузку.
Фактически runtime выступает как диспетчер загрузки JavaScript-модулей внутри приложения.

Как смотреть чанки в DevTools

В браузере можно анализировать загрузку чанков через инструменты разработчика (DevTools). Чаще всего для этого используют вкладку Network.
Во вкладке Network отображаются все сетевые запросы, которые браузер выполняет при открытии сайта и навигации внутри приложения.
Например, при первом открытии страницы могут загружаться:
main.js
vendors.js
runtime.js
styles.css
А при переходе пользователя в профиль дополнительно может появиться profile.chunk.js.
Это означает, что приложение использует lazy loading и загружает код страницы только в момент необходимости.
Через DevTools можно проверить:
  • какие чанки загружаются сразу;
  • какие подгружаются позже;
  • размер файлов;
  • время загрузки;
  • HTTP-статусы;
  • использование кэша;
  • ошибки загрузки.
Для анализа загрузки чанков обычно открывают DevTools, переходят во вкладку Network и включают фильтр JS, после чего обновляют страницу и смотрят, какие JavaScript-файлы загрузились сразу при открытии приложения. Затем выполняют переходы между страницами или открывают различные элементы интерфейса и проверяют, появляются ли в списке запросов новые .chunk.js файлы. Это позволяет понять, какие части приложения загружаются сразу, а какие - только при выполнении определенных действий пользователя.

Тестирование

Ошибки здесь часто проявляются нестабильно и зависят от качества сети, кэширования и навигации пользователя.
Тестировщику стоит проверять:
  • корректную загрузку страниц при медленном интернете;
  • отсутствие бесконечных loader/spinner;
  • корректную работу lazy loading;
  • быстрые переходы между страницами;
  • поведение приложения после релиза;
  • работу кэширования;
  • ошибки загрузки chunk-файлов.
Частые проблемы:
  • chunk не загрузился из-за плохой сети;
  • белый экран при navigation;
  • ChunkLoadError после релиза;
  • 404 Not Found для .chunk.js;
  • зависший lazy-loaded экран;
  • race condition при быстрых переходах;
  • broken cache;
  • неправильный prefetch/preload.
Подобные проблемы с загрузкой чанков могут приводить к различным сбоям в работе SPA-приложения. В зависимости от сценария пользователь может столкнуться с зависанием интерфейса, бесконечной загрузкой отдельных экранов или элементов, некорректным отображением UI, ошибками навигации между страницами и даже полным падением приложения. В некоторых случаях перестают открываться отдельные разделы сайта, поскольку браузер не может загрузить или выполнить необходимый chunk-файл.

Обсудить статью можно в канале «Тестировщики нужны» — в Telegram, MAX и Сетке.