← Назад

Ленивая загрузка и код-сплиттинг: не грузите лишнее.

Оптимизация LCP

В крупных веб-приложениях десятки компонентов, объёмные библиотеки и множество изображений нередко превращают первую загрузку в настоящее испытание. Пользователи раздражаются, уходят, а позиции в поисковиках медленно сползают вниз. Ленивая загрузка и код-сплиттинг позволяют браузеру работать избирательно: получать только то, что требуется прямо сейчас, и заметно сокращать стартовый объём данных.

Ленивая загрузка в действии

Суть ленивой загрузки в том, чтобы отложить ресурсы до момента реальной необходимости. Браузер не тянет сразу всё — изображения, видео, модули кода. Они приходят по запросу: при прокрутке, клике или переходе на нужный участок страницы.
Ленивая загрузка: loading= В HTML5 для изображений и iframe достаточно одного атрибута loading="lazy". Браузер самостоятельно следит за видимостью и начинает загрузку. Такой подход особенно спасает на длинных страницах — в статьях, галереях, интернет-магазинах. В JavaScript принцип тот же: динамический импорт или готовые хелперы. Результат — быстрее старт и меньше расхода трафика на мобильных устройствах.

Код-сплиттинг: делим бандл с умом

Код-сплиттинг разбивает JavaScript-бандл на компактные независимые части, которые загружаются только при необходимости. Вместо одного большого файла в несколько мегабайт приложение получает основной чанк для критического пути и дополнительные — под конкретные страницы или возможности.
Webpack, Vite, Rollup сами создают такие чанки, когда видят динамический импорт. В React это удобно делать через React.lazy() и Suspense:

JS

// Находим блок, куда вставим Dashboard
const root = document.getElementById('root');

//Показываем заглушку (Аналог fallback=)
root.textContent = 'Загрузка...';

//Лениво грузим файл (Аналог React.lazy и import)
import('./Dashboard.js').then(() => {
  
//Файл скачался — убираем загрузку и показываем Dashboard
root.textContent = 'Тяжелый Dashboard загружен!';

});
Dashboard и всё, что с ним связано, появится в браузере лишь тогда, когда пользователь действительно до него доберётся. Код-сплиттинг

Вместе они сильнее

Код-сплиттинг готовит отдельные файлы, ленивая загрузка решает момент их запроса. Без первого второй просто нечего будет подгружать. В связке они дают реальный прирост производительности: начальный бандл часто становится легче в 2–5 раз, в зависимости от архитектуры проекта.

Чаще всего разработчики применяют три варианта:

1. По маршрутам — каждая страница в React Router живёт в своём чанке. 2. По компонентам — модальные окна, сложные формы, графики, редакторы. 3. По библиотекам — тяжёлые зависимости вроде Chart.js или функций работы с датами подключаются только где нужно.

Когда это имеет смысл, а когда — нет

Оптимизация оправдана, если Time to Interactive превышает 3–4 секунды, есть разделы, которые открывают меньше половины пользователей, или сжатый бандл уже перевалил за 500–700 КБ. В растущих проектах эффект почти всегда перекрывает затраты. В простых лендингах или небольших админках с десятком компонентов дополнительные запросы и управление состоянием загрузки могут только навредить. Критические элементы — шапка, навигация, основной контент — лучше держать в основном бандле с самого начала.

Подводные камни, которые стоит знать

Самая частая проблема - резкая «вспышка» загрузки: на месте компонента внезапно появляется пустое пространство или крутящийся индикатор. Решить это помогают хорошо продуманные fallback-компоненты (временные заглушки) и prefetching — предварительная загрузка чанков для тех переходов, которые легко предсказать по поведению пользователя.

Также распространённой ошибкой является чрезмерное дробление кода. Когда разработчик выносит в отдельные чанки буквально каждый мелкий компонент, количество HTTP-запросов растёт, а браузер тратит лишнее время на их обработку. В итоге вместо ускорения можно получить обратный эффект: страница начинает загружаться медленнее, особенно на слабых соединениях. Правило простое — сплиттить имеет смысл только заметно тяжёлые или редко используемые части, а не всё подряд.

Ещё одна типичная проблема — ослабление tree shaking (отсечения мёртвого кода). Бандлер по умолчанию удаляет неиспользуемые функции и модули, чтобы уменьшить размер файла. Но если динамические импорты настроены небрежно, часть лишнего кода остаётся в основном чанке, увеличивая его вес. Инструменты вроде webpack-bundle-analyzer сразу показывают картину: что и куда попало.

Не стоит забывать и о сетевых сбоях. Если чанк не загрузился из-за проблем с интернетом, приложение может полностью упасть. Чтобы этого избежать, обязательно оборачивайте lazy-компоненты в Error Boundary, чтобы пользователь увидел понятное сообщение вместо белого экрана или краша всего приложения.

Практика, которая работает

Начните с анализа текущего бандла — посмотрите, где самые «жирные» куски. Выделите в отдельные чанки маршруты и редко используемые возможности. Для изображений сочетайте loading="lazy" с WebP/AVIF и запасным вариантом. Тестируйте обязательно на мобильных устройствах с throttled-соединением: Lighthouse в этом режиме покажет реальные цифры.

Ленивая загрузка и код-сплиттинг не превращают тяжёлое приложение в мгновенную молнию, но позволяют точно дозировать, что и когда получает браузер. В итоге растёт конверсия, снижается bounce rate и улучшаются Core Web Vitals — метрики, которые важны и для SEO, и для того, чтобы людям было приятно работать с вашим продуктом. Внедряйте изменения постепенно, замеряя всё на каждом шаге. В серьёзных проектах разница чувствуется не только в отчётах, но и в живых отзывах пользователей, которым больше не приходится ждать, пока загрузится каждая страница.

#Код сплиттинг #ленивая загрузка #javascript #ускорение загрузки