Оптимизация производительности приложения за счет разделения компонентов, маршрутов и библиотек

Когда вы развертываете приложение React с помощью такого инструмента, как webpack, вы применяете метод, называемый объединением.

Инструменты сборки, такие как webpack, в конце концов, являются сборщиками модулей.

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

Однако часто, когда мы создаем страницу, мы включаем довольно много кода, который не нужен немедленно.

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

Один из способов добиться этого - разделение кода.

Разделение кода позволяет нам отложить загрузку различных ресурсов на потом - когда они действительно понадобятся.

Например, предположим, что пользователь попадает на маршрут и попадает на страницу в вашем веб-приложении.

Возможно, на этой странице есть несколько тяжелых модальных окон.

Возможно, у этой страницы есть несколько маршрутов, которые загружают дополнительный контент в другое место.

Возможно, он содержит тяжелую библиотеку, которая понадобится позже, но сначала загружается на домашнюю страницу.

Если наша цель состоит в том, чтобы отображать содержимое страницы как можно быстрее, нам нужно абстрагироваться от всего, что не требуется немедленно и замедляет время загрузки.

Давайте рассмотрим несколько способов разделения кода вашего веб-приложения с помощью lazy метода React и Suspense компонента.

Настраивать

Во-первых, давайте загрузим проект с create-react-app.

В вашей командной строке:

Затем запустите сервер разработки на port:3000, выполнив установку:

Отлично, у нас есть базовый вращающийся логотип React, к которому мы привыкли.

Откройте проект в своем любимом редакторе, и приступим.

Настройка проекта

В React у нас есть возможность импортировать функцию с именем lazy и компонент с именем Suspense.

lazy позволяет нам отложить загрузку компонента или ресурса до тех пор, пока он не понадобится.

В сочетании с Suspense компонент lazy будет отображаться только после загрузки, и мы можем предоставить запасной вариант во время его загрузки (например, loading...).

Давайте рассмотрим пример.

Доступ к маршрутизатору и настройка маршрута

Выключите сервер с помощью Ctrl + c и установите Reach Router:

Reach Router - это простой и легкий маршрутизатор, разработанный разработчиками React Router. - Документация по маршрутизатору охвата

В вашем терминале:

Что мы собираемся сделать сейчас:

  1. Вытяните код вращающегося логотипа React в отдельный компонент под названием Main.js.
  2. Используйте ReachRouter, чтобы по умолчанию отображать Main.
  3. Создайте новый компонент, который будет перенаправлен, когда мы щелкнем логотип React.

Итак, создайте новый файл с именем Main.js и вытащите код из <header> из App.js.

Наш App.js теперь будет выглядеть намного тоньше.

Убедитесь, что вы импортировали Main.js и поместили его там, где вы его удалили, как показано ниже.

Как всегда, избегайте этих методов класса.

Большой!

Так что визуально ничего не изменится.

Пока мы втягивали код в новый компонент, код не изменился, поэтому все будет выглядеть так же.

Теперь давайте импортируем ReachRouter и используем наш компонент Main в качестве маршрута по умолчанию.

ReachRouter очень просто использовать:

  1. Импортируйте Router из библиотеки ReachRouter.
  2. Оберните свои маршруты в <router>.
  3. Обеспечьте path опору для каждого маршрута, по умолчанию Main.

Обновите App.js сейчас следующим образом

Опять же, визуально ничего не изменится, но теперь мы установили Main в качестве маршрута по умолчанию.

Теперь давайте создадим второй дочерний маршрут, назначим ему путь и сделаем ссылку с логотипом React на этот путь.

Создайте новый файл с именем SplitThis.js и настройте его так, чтобы его имя просто отображалось как <h1>.

Затем импортируйте этот компонент в App.js и добавьте его как дочерний маршрут в <Main> с путем "/split".

Затем в Main импортируйте Link из @reach/router, чтобы обернуть логотип React, и направьте его на "/split".

Теперь мы видим, что наши маршруты настроены и что щелчок по логотипу переводит нас на другую страницу.

Маршруты и компоненты разделения кода

Во-первых, чтобы понять, как работает объединение, давайте откроем наш инспектор в нашем браузере.

В инспекторе выберите Сеть ➡ JS и обновите страницу.

Когда вы обновитесь, вы увидите, что по сети проходят разные пакеты.

Вы также можете увидеть их размеры. Прямо сейчас все наши пакеты очень и очень маленькие.

Обычно мы даже не рассматриваем разделение кода, если размер пакета не превышает 30 КБ.

Но для примера давайте импортируем lazy и Suspense и разделим наш SplitThis маршрут.

Обновите App.js, чтобы включить указанный выше импорт, оберните маршруты в Suspense резервным тегом и импортируйте SplitThis лениво.

Если SplitThis lazy загружен в Suspense, этот компонент не будет включен в основной пакет.

Вместо этого он будет получен с сервера только тогда, когда пользователь запросит его, щелкнув логотип React.

Посмотрите, что происходит теперь, когда мы загружаем приложение, а затем переходим к нашему SplitThis маршруту:

Мы видим, что маршрут SplitThis был загружен как отдельный пакет.

Примечание. Еще одна очень важная вещь, на которую следует обратить внимание: как только пакет загружен и вы перейдете в другое место, он не будет перезагружен, когда вы вернетесь.

Сборщик достаточно умен, чтобы видеть, что требуемый пакет уже был загружен ранее, и не пытается получить его снова.

Библиотеки разделения кода

Некоторые библиотеки очень тяжелые.

Обычно, если вы не планируете использовать абсолютно всю библиотеку, вам следует импортировать только те части, которые вам нужны.

Так же, как мы делали с разделением кода маршрута, давайте сделаем то же самое с библиотекой внутри компонента.

Во-первых, давайте установим тяжелую библиотеку для импорта, например moment.js.

Выключите сервер и установите библиотеку moment.

Теперь просто импортируйте moment в SplitThis.js.

Кроме того, давайте также импортируем lodash, который входит в состав create-react-app.

Теперь посмотрим на нагрузку в сети.

Щелкнув по нашему дочернему маршруту, мы увидим следующие сетевые результаты:

Первые три строки - это наша начальная загрузка в main, а затем, когда мы щелкаем наш дочерний маршрут, мы получаем еще два пакета, один из которых довольно большой, поскольку он импортирует две большие библиотеки.

Что мы узнали

Используя lazy метод React и компонентSuspense, мы получаем возможность контролировать, как сборщик приложений решает, что идет куда.

Результат: скудные страницы, которые загружаются быстро (при правильном использовании).

Никто не хочет упорно трудиться над созданием классного приложения только для того, чтобы пользователи уходили из-за медленной первой отрисовки.

Так что будь ленивым.

Спасибо за прочтение!