Узнайте, как ускорить время начальной загрузки с помощью функции разделения кода Webpack (на примерах с использованием React)

Основная цель Webpack - подготовить ваши файлы JavaScript, чтобы они могли использоваться браузером.

Это делается путем сканирования вашего кода JavaScript из точки входа (обычно файла index.js) и последующего выполнения инструкций import, написанных в этой точке входа.

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

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

Вот диаграмма, иллюстрирующая процесс объединения Webpack:

Есть и другие функции, которые Webpack предлагает разработчикам JavaScript, например:

  • Используйте компилятор (обычно Babel) для преобразования вашего современного синтаксиса JavaScript (ES 6/7/8 и выше) в синтаксис, понятный большинству браузеров (ES 5).
  • Преобразуйте SASS в CSS, чтобы браузеры понимали ваши правила стилей

Тем не менее, комплектация - это основная причина, по которой вам нужно использовать Webpack для разработки приложений JavaScript.

Почему разделение кода - отличная функция

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

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

Если размер вашего bundle.js файла JavaScript составляет 10 мегабайт, то выполнение вашего файла JavaScript происходит после того, как клиент загрузил файл размером 10 мегабайт.

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

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

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

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

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

Затем давайте посмотрим на пример разделения кода в действии с использованием React.

Пример разделения кода с помощью React

В React разделение кода включает применение динамического синтаксиса import() к вашим компонентам, так что webpack автоматически разделяет импортированный компонент как отдельный пакет.

Если вы загружаете свое приложение React с помощью Create React App (CRA), то конфигурация веб-пакета, сгенерированная CRA, уже включает разделение кода по умолчанию.

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

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



Приложение React для демонстрации разделения кода состоит из двух компонентов:

  • Компонент Home со ссылкой на компонент Login
  • Компонент Login, который использует Formik и Axios для получения пользовательского ввода и отправки запроса POST.

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

Разделение кода для примера приложения происходит внутри файла index.js, где компоненты импортируются динамически, когда они необходимы React Router.

Внутри файла index.js вы увидите следующий код:

import React, { Suspense, lazy } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
const Home = lazy(() => import("./components/Home"));
const Login = lazy(() => import("./components/Login"));
const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/Login" component={Login} />
      </Switch>
    </Suspense>
  </Router>
);

В приведенном выше коде компоненты Home и Login сначала импортируются динамически с помощью функции import(), которая возвращает объект Promise и запускает асинхронную задачу для загрузки компонента.

Затем вызывается функция lazy() из библиотеки React, чтобы сообщить React, что компонент загружается динамически. Эта функция позволяет React дождаться разрешения Promise от import() и возврата модуля.

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

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

В Терминале запустите команду npm run build:

Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
1.19 KB   build/static/js/runtime-main.bb267bc3.js
451 B     build/static/js/main.20015095.chunk.js
290 B     build/static/css/main.899c8c77.chunk.css
15.4 KB   build/static/js/2.df805033.chunk.js
49.41 KB  build/static/js/3.6f1ca6de.chunk.js
236 B     build/static/js/4.2dd3ffe8.chunk.js
588 B     build/static/js/5.b17fde7d.chunk.js

Конфигурация веб-пакета от CRA включает добавление хэша для предотвращения кэширования пакета браузером при его изменении.

Пояснения к сгенерированным файлам выше можно найти в документации CRA здесь. Короче:

  • файл runtime-main.[hash].js - это логика выполнения веб-пакета, которая будет запускать ваше приложение.
  • Файл main.[hash].chunk - это основная точка входа в ваше приложение, которым в нашем примере является файл index.js.
  • Файлы [number].[hash].chunk.js предназначены для сторонних библиотек, таких как код библиотеки react, axios и formik, который импортируется в приложение.
  • Техника разделения кода также создаст chunk.js файл, поэтому вам нужно проверить файл и посмотреть, предназначен ли фрагмент для node_modules кода или кода вашего приложения.
  • Также имеется один chunk.css файл, в котором хранится стиль CSS, используемый для приложения.

Изучив код, вы увидите, что файл 2.chunk.js содержит весь код библиотеки для компонента Login, который включает axios и formik, а файл 5.chunk.js содержит код компонента Login.

Код для библиотеки React создается внутри файла 3.chunk.js, а файл 4.chunk.js содержит код для компонента Home.

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

Попробуем сравнить результат выполнения команды build без динамического импорта.

Удалите import(), Suspense и lazy() из файла index.js, как показано ниже:

import Home from "./components/Home";
import Login from "./components/Login";
import "./index.css";
const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/Login" component={Login} />
    </Switch>
  </Router>
);

Затем вам нужно снова запустить команду build из Терминала. Вот результат компиляции с моего компьютера:

Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
776 B     build/static/js/runtime-main.aaee48c5.js
770 B     build/static/js/main.68588f39.chunk.js
290 B     build/static/css/main.899c8c77.chunk.css
64.33 KB  build/static/js/2.2328eeea.chunk.js

Как видите, три chunk.js файла из предыдущей сборки отсутствуют в сгенерированном выше выводе.

Приведенный выше 2.chunk.js файл содержит код для всех ваших сторонних библиотек, а код приложения находится внутри main.chunk.js файла.

Хотя вам не понадобятся библиотеки formik и axios, прежде чем вы откроете Login страницу, обе библиотеки будут загружены из файла фрагмента без реализации функции разделения кода.

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

Заключение

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

Инструменты OSS, такие как Bit, предлагают мощные возможности разработчика именно для этого. Многие команды начинают с создания своих дизайн-систем или микро-интерфейсов через компоненты. Попробуйте →

Заключение

Современные приложения JavaScript, как правило, имеют один большой bundle.js файл в результате процесса объединения веб-пакетов.

Файл bundle.js требуется браузеру для запуска вашего приложения, поэтому чем больше размер пакета, тем больше времени требуется для загрузки вашего приложения в браузере пользователя.

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

Автономные команды строят вместе

Создание монолитных приложений означает, что все работают вместе, в одной кодовой базе и над одной раздутой версией. Это часто делает разработку болезненной и медленной при масштабировании.

Но что, если вместо этого вы сначала создаете независимые компоненты, а затем составляете приложения? Автономные команды, строим вместе!

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

Инструменты OSS, такие как Bit, предлагают мощные возможности разработчика именно для этого. Многие команды начинают с создания своих дизайн-систем или микро-интерфейсов через компоненты. Попробуйте →

Учить больше







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

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

Для получения дополнительной информации о функции разделения кода вы можете посетить документацию по разделению кода веб-пакета.