Spec-Zone.ru › React 17

Разделение кода

Сборка

Большинство приложений React будут иметь свои файлы, «собранные» с помощью инструментов, таких как Webpack, Rollup или Browserify. Сборка — это процесс следования за импортированными файлами и объединения их в один файл: «сборку». Затем эту сборку можно включить на веб-странице, чтобы загрузить всё приложение сразу.

Пример

Приложение:

// app.js
import { add } from './math.js';

console.log(add(16, 26)); // 42
// math.js
export function add(a, b) {
  return a + b;
}

Сборка:

function add(a, b) {
  return a + b;
}

console.log(add(16, 26)); // 42

Примечание:

Ваши сборки будут выглядеть совершенно иначе.

Если вы используете Create React App, Next.js, Gatsby или похожий инструмент, у вас будет настроенный Webpack для сборки вашего приложения.

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

Разделение кода

Сборка — это здорово, но по мере роста приложения, будет расти и ваш бандл. Особенно, если вы включаете большие сторонние библиотеки. Вам нужно следить за кодом, который вы включаете в свою сборку, чтобы случайно не сделать её слишком большой, из-за чего приложение будет долго загружаться.

Чтобы избежать больших сборок, полезно заранее «разделить» сборку. Разделение кода — это функция, поддерживаемая такими сборщиками, как Webpack, Rollup и Browserify (через factor-bundle), которые могут создавать несколько сборок, которые можно динамически загружать во время выполнения.

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

import()

Лучший способ добавить разделение кода в ваше приложение — через динамический import() синтаксис.

До:

import { add } from './math';

console.log(add(16, 26));

После:

import("./math").then(math => {
  console.log(math.add(16, 26));
});

Когда Webpack встречает этот синтаксис, он автоматически начинает разделять код вашего приложения. Если вы используете Create React App, это уже настроено за вас, и вы можете начать использовать его сразу. Он также поддерживается в Next.js по умолчанию.

Если вы настраиваете Webpack самостоятельно, вам, вероятно, захочется прочитать руководство Webpack по разделению кода. Настройка Webpack должна примерно соответствовать этому.

При использовании Babel, вам нужно убедиться, что Babel может парсить синтаксис динамического импорта, но не преобразовывать его. Для этого вам понадобится @babel/plugin-syntax-dynamic-import.

React.lazy

Примечание:

React.lazy и Suspense пока недоступны для рендеринга на стороне сервера. Если вы хотите выполнить разделение кода в приложении, рендерящемся на стороне сервера, мы рекомендуем Loadable Components. У него есть хорошее руководство по разделению сборок с рендерингом на стороне сервера.

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

До:

import OtherComponent from './OtherComponent';

После:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

Это автоматически загрузит сборку, содержащую OtherComponent, когда этот компонент будет впервые рендерен.

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

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

import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}

Свойство fallback принимает любые React элементы, которые вы хотите отображать, пока компонент загружается. Вы можете разместить компонент Suspense где угодно выше lazy компонента. Вы даже можете обернуть несколько lazy компонентов с помощью одного компонента Suspense.

import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}

Обработка ошибок

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

import React, { Suspense } from 'react';
import MyErrorBoundary from './MyErrorBoundary';

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

const MyComponent = () => (
  <div>
    <MyErrorBoundary>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </MyErrorBoundary>
  </div>
);

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

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

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

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

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

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

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);

Именованные экспорты

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

// 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"));
Полезная ли эта страница?

© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://17.reactjs.org/docs/code-splitting.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API