---
layout: post
title: Сокращение размера полезной нагрузки JavaScript за счет разделения кода
authors:
  - houssein
description: Чрезмерно большой размер полезной нагрузки JavaScript существенно замедляет скорость вашего сайта. Вместо того чтобы отправлять пользователю весь JavaScript-код при первой же загрузке страницы вашего приложения, разбейте бандл на несколько фрагментов и в самом начале пересылайте только самый необходимый код.
date: 2018-11-05
codelabs:
  - codelab-code-splitting
tags:
  - performance
---

Никто не любит долго ждать. **[Более 50% пользователей покидают сайт, если он загружается дольше 3 секунд](https://www.thinkwithgoogle.com/intl/en-154/insights-inspiration/research-data/need-mobile-speed-how-mobile-latency-impacts-publisher-revenue/)**.

Чрезмерно большой размер полезной нагрузки JavaScript существенно замедляет скорость вашего сайта. Вместо того чтобы отправлять пользователю весь JavaScript-код при первой же загрузке страницы вашего приложения, разбейте бандл на несколько фрагментов и в самом начале пересылайте только самый необходимый код.

## Мера

Если на загрузку всего JavaScript-кода на странице тратится слишком много времени, проверка в Lighthouse завершается неудачей.

{% Img src="image/admin/p0Ahh3pzXog3jPdDp6La.png", alt="Неудачно завершившаяся проверка в Lighthouse, показывающая, что на загрузку скриптов тратится слишком много времени.", width="797", height="100" %}

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

Популярные упаковщики модулей, такие как [webpack](https://webpack.js.org/guides/code-splitting/), [Parcel](https://parceljs.org/code_splitting.html) или [Rollup](https://rollupjs.org/guide/en#dynamic-import), позволяют разбивать бандлы на части, используя [динамический импорт](https://v8.dev/features/dynamic-import). Например, давайте рассмотрим следующий фрагмент кода с примером метода `someFunction`, который вызывается при отправке формы.

```js
import moduleA from "library";

form.addEventListener("submit", e => {
  e.preventDefault();
  someFunction();
});

const someFunction = () => {
  // uses moduleA
}
```

В данном примере метод `someFunction` использует модуль, импортируемый из библиотеки. Если этот модуль не используется где-либо еще, блок кода можно изменить таким образом, чтобы он использовал динамический импорт и загрузка модуля происходила только при отправке формы пользователем.

```js/2-5
form.addEventListener("submit", e => {
  e.preventDefault();
  import('library.moduleA')
    .then(module => module.default) // using the default export
    .then(someFunction())
    .catch(handleError());
});

const someFunction = () => {
    // uses moduleA
}
```

Теперь код этого модуля не будет включен в начальный бандл и будет загружаться в **отложенном режиме**. Пользователь будет получать его только при отправке формы, когда в нем возникнет необходимость. Чтобы еще больше повысить производительность страницы, используйте [предварительную загрузку критически важных фрагментов, чтобы их загрузка происходила с более высоким приоритетом](/preload-critical-assets).

Хотя приведенный выше фрагмент кода — простой пример, в более крупных приложениях отложенная загрузка сторонних зависимостей применяется нечасто. Обычно сторонние зависимости выносятся в отдельный бандл поставщика, который можно кешировать, поскольку они обновляются не так часто. Помочь вам с этой задачей может [**SplitChunksPlugin**](https://webpack.js.org/plugins/split-chunks-plugin/).

При использовании фреймворка, работающего на стороне клиента, более простым подходом к отложенной загрузке частей приложения является разбивка на уровне маршрутов или компонентов. Многие популярные фреймворки, использующие webpack, предоставляют абстракции для упрощения отложенной загрузки без необходимости настраивать ее вручную.
