Главная Категории Контакты Поиск

Разделение кода в React или Code Splitting

Что такое Code Splitting и как его использовать в React.

React·10.01.2019·читать 3 мин 🤓·Автор: Alexey Myzgin

Современные JavaScript приложения могут быть довольно большими с точки зрения размера bundle пакета. Вам бы не хотелось, чтобы ваши пользователи загружали JavaScript пакет объемом в 1 МБ (ваш код и библиотеки, которые вы используете) только для загрузки первой страницы, верно? Но это то, что происходит по умолчанию, в современном веб-приложении, собраном с помощью Webpack.

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

Разделение кода - это практика загрузки только того JavaScript-кода, который вам нужен в определенный момент времени и тогда, когда вам это нужно.

Это улучшает:

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

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

React.lazy и Suspense образуют идеальный способ ленивой загрузки зависимости по необходимости.

Важно!

React.lazy и Suspense пока недоступны для server-side сборки. Для этого лучше использовать Loadable Components. У них есть хорошая документация.

React.lazy

Давайте начнем с React.lazy. Вы используете его для импорта любого компонента.

Важно!

Синтаксис динамического импорта import() - это предложение ECMAScript (JavaScript), которое в настоящее время не является частью языкового стандарта. Ожидается, что он будет принят в ближайшее время.

import React from "react";

const TodoList = React.lazy(() => import("./TodoList"));

export default () => {
  return (
    <div>
      <TodoList />
    </div>
  );
};

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

Suspense

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

import React from "react";

const TodoList = React.lazy(() => import("./TodoList"));

export default () => {
  return (
    <div>
      <React.Suspense>
        <TodoList />
      </React.Suspense>
    </div>
  );
};

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

Используйте его свойство fallback для вывода индикатора загрузки:

...
  <React.Suspense fallback={<p>Loading...</p>}>
    <TodoList />
  </React.Suspense>
...

Error boundaries

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

import React from "react";
import MyErrorBoundary from "./MyErrorBoundary";
const TodoList = React.lazy(() => import("./routes/TodoList"));
const NewTodo = React.lazy(() => import("./routes/NewTodo"));

const App = () => (
  <div>
    <MyErrorBoundary>
      <React.Suspense fallback={<p>Loading...</p>}>
        <section>
          <TodoList />
          <NewTodo />
        </section>
      </React.Suspense>
    </MyErrorBoundary>
  </div>
);

Разделение кода на основе маршрутов

Вот пример того, как настроить разделение кода на основе маршрутов, используя такие библиотеки, как React Router с React.lazy.

import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

const Home = React.lazy(() => import("./routes/Home"));
const About = React.lazy(() => import("./routes/About"));

const App = () => (
  <Router>
    <React.Suspense fallback={<p>Loading...</p>}>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/new" component={About} />
      </Switch>
    </React.Suspense>
  </Router>
);

Именной экспорт

React.lazy в настоящее время поддерживает только экспорт по умолчанию (default exports). Если модуль, который вы хотите импортировать, использует именной экспорт (named exports), вы можете создать промежуточный модуль, который реэкспортирует его по умолчанию.

// ManyComponents.js
export const MyComponent = /* ... */;
export const MyUnusedComponent = /* ... */;
// MyComponent.js
export { MyComponent as default } from "./ManyComponents.js";
// MyApp.js
import React, { lazy } from "react";
const MyComponent = lazy(() => import("./MyComponent.js"));

Источник: Code-Splitting

Website, name & logo
Copyright © 2022. Alex Myzgin