
В этом году мы собираемся отпраздновать 10-летие React! Поскольку он был с открытым исходным кодом, он доминировал во фронтенд-разработке. React стал наиболее используемым веб-фреймворком среди мировых разработчиков программного обеспечения с 2021 года. Это имеет смысл, поскольку его сравнительно легко изучить, его несложно использовать, поддерживать и тестировать, он эффективен, хорошо работает и имеет богатый пользовательский интерфейс. По данным SimilarTech, по состоянию на март 2023 года с помощью React было создано 1 345 024 веб-сайта.

В этом блоге мы собираемся обсудить, почему React стал популярным выбором для фронтенд-разработки и как расставить приоритеты для пользователей с некоторыми практическими примерами.
Я собираюсь сосредоточиться на двух функциях и идеях, которые помогут вам улучшить взаимодействие с пользователем и процесс разработки. Давайте углубимся.
Отложенная загрузка — как дела?
Отложенная загрузка React — это метод, который в последние годы становится все более популярным среди разработчиков интерфейса. Это включает в себя разделение кода вашего приложения на более мелкие фрагменты или модули, которые загружаются по запросу, а не все сразу. В этом разделе мы обсудим, почему ленивая загрузка считается хорошей практикой для фронтенд-разработчиков, как она работает за кулисами, и приведем несколько примеров того, как она может повысить производительность вашего приложения.
Прежде всего, отложенная загрузка позволяет разработчикам значительно сократить время первоначальной загрузки своих приложений. Когда пользователь открывает веб-страницу, вся кодовая база приложения должна быть загружена и выполнена браузером. Этот процесс может занять несколько секунд или больше, особенно если приложение большое или сложное. Разделяя код на более мелкие, более управляемые модули и загружая их только тогда, когда они необходимы, разработчики могут сократить время первоначальной загрузки своего приложения и улучшить общее взаимодействие с пользователем.
За кулисами ленивая загрузка работает с использованием динамической функции import() в JavaScript. Эта функция позволяет вам загружать модуль асинхронно, что означает, что он не будет блокировать основной поток выполнения во время его загрузки. Вместо этого модуль будет загружаться в фоновом режиме, а затем выполняться после полной загрузки. Это может быть особенно полезно для больших модулей или модулей, которые нужны только в определенных частях приложения.
Разделение вашего приложения на несколько частей связано с рядом проблем, таких как решение о том, что поместить в каждый фрагмент и когда его загружать, чтобы пользователю было удобно работать.
Как это использовать
Одним из примеров того, как отложенная загрузка может быть использована на практике, является React Router. Отложенная загрузка компонентов, связанных с определенными маршрутами, гарантирует загрузку только того кода, который необходим для каждой отдельной страницы. Это может быть значительным улучшением по сравнению с загрузкой всех компонентов для всего приложения заранее, особенно если ваше приложение имеет много разных маршрутов.
В этом примере мы видим простое приложение, отображающее два маршрута. Первый маршрут, который увидит пользователь, — это HomePage, и только если он перейдет на /customer, браузер загрузит остальную часть кода, чтобы пользователь увидел страница клиента.
Витрина Eager VS ленивой загрузки
Допустим, наше требование состоит в том, чтобы создать и отобразить предварительный просмотр файла PDF с квитанцией клиента, когда пользователь нажимает кнопку, и мы знаем, что эта функция не очень часто используется на стороне клиента.

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

Нетерпеливая загрузка
Первый подход предполагает импорт компонента сразу после загрузки страницы — без разделения на несколько фрагментов.



Когда мы загружаем страницу в первый раз, весь js-код загружается сразу, даже если в настоящее время мы не потребляем контент.
Ленивая загрузка
Давайте внесем небольшие изменения, чтобы мы могли разделить наше приложение на несколько частей. Таким образом, мы уменьшаем время первоначальной загрузки страницы.

Давайте разберем
const SomeExpensiveComponent = React.lazy( () => import(/* webpackChunkName: "this_is_expansive" */ 'components/SomeExpensiveComponent') );
В строке 6 мы заменили импорт на
`React.lazy`, поэтому react не будет импортировать компонент, пока он не будет использован. Webpack поддерживает специальный синтаксис комментариев, называемый «магическими комментариями», который позволяет вам называть разные фрагменты. Пакеты, которые мы загружаем, работают нормально, как есть, но они не очень удачно названы.0.chunk.jsи1.chunk.jsмогут выполнять свою работу, но они не подходят для отладки ошибок в рабочей среде.
<React.Suspense fallback={<CircularProgress msg="Loading..." />}>
{showExpensiveComponent && <SomeExpensiveComponent />}
</React.Suspense>
В строке 28 мы заключаем компонент
<SomeExpensiveComponent />в компонент<Suspense>и указываем резервный пользовательский интерфейс, который будет отображаться во время загрузки компонента. В этом случае мы просто отображаем загрузчик с сообщением «Загрузка...».
Простота React справится со всеми асинхронными сложностями.
Окончательный результат


Давайте использовать его везде (?)
Итак, краткий ответ: НЕТ. Позвольте мне объяснить: при создании отличного пользовательского интерфейса приложение должно быть отзывчивым и быстрым. Когда мы решаем разделить код нашего приложения на несколько небольших фрагментов, нам нужно помнить, что каждый раз, когда пользователь щелкает и пытается использовать контент в первый раз, он будет лениво загружать определенный фрагмент кода. Пока это не будет сделано, он будет отображать резервный компонент по умолчанию, который мы определили в нашем компоненте Suspense. Таким образом, в случае, когда у нас есть несколько чанков, на экране будет отображаться несколько загрузчиков.

Как мы его используем в Melio
Наша команда инструментов в Melio обслуживает множество разных команд в разных организациях, и у каждой команды есть свои роли и разрешения. Например, команда А будет использовать только определенные приложения из продукта «Инструменты», поэтому при загрузке приложения нет необходимости загружать все остальные приложения. Это значительно уменьшит размер пакета и поможет улучшить взаимодействие с пользователем.
В заключение, будьте ленивы (не совсем так).
Ленивая загрузка — это мощный метод, который может помочь улучшить производительность вашего внешнего приложения. Разбивая свой код на более мелкие, более управляемые фрагменты и загружая их по требованию, вы можете сократить время загрузки, сэкономить пропускную способность, лучше управлять сложностью своего кода и обеспечить лучший пользовательский опыт. При правильном использовании отложенная загрузка может стать мощным инструментом для оптимизации производительности современных веб-приложений.
Если вы фронтенд-разработчик, определенно стоит подумать о том, как включить отложенную загрузку в свои собственные проекты.
Бонус
В начале блога я упомянул, что собираюсь рассказать о двух основных функциях. Итак, теперь пришло время поговорить об обработке ошибок в React.
Если вы разработчик React, возможно, вы сталкивались с ситуацией, когда ваше приложение аварийно завершает работу из-за необработанных ошибок в ваших компонентах. Это может разочаровать как разработчика, так и конечного пользователя. Чтобы решить эту проблему, React предоставляет функцию под названием ErrorBoundary.
ErrorBoundary — это компонент React, который перехватывает ошибки в своих дочерних компонентах и отображает резервный пользовательский интерфейс вместо аварийного дерева компонентов. Таким образом, ваше приложение может корректно восстанавливаться после ошибок, а пользователь может продолжать использовать его без прерывания работы.

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

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

Давайте углубимся в код

Компонент класса становится границей ошибки, если он определяет один (или оба) из методов жизненного цикла
static getDerivedStateFromError()илиcomponentDidCatch(). Используйтеstatic getDerivedStateFromError()для отображения резервного пользовательского интерфейса после возникновения ошибки. ИспользуйтеcomponentDidCatch()для регистрации информации об ошибке. [документация по реакции.org]
В этом примере мы предоставляем универсальный компонент, который может принимать резервный компонент и в случае ошибки отображать его вместо this.props.children.
Помимо перехвата ошибок, ErrorBoundary также предоставляет способ регистрации этих ошибок в API или другой внешней службе. Это важно для отладки и устранения неполадок вашего приложения. Регистрируя ошибки, вы можете лучше понять, что их вызывает, и предпринять шаги, чтобы предотвратить их появление в будущем. Это может быть особенно полезно в производственных средах, где может быть сложно воспроизвести ошибку.
override componentDidCatch(error, errorInfo) {
this.setState({
hasError: true,
error
});
// API service we use to provide information about the error
logger.error(error, { errorInfo });
}
Отличные сторонние API-сервисы, обеспечивающие управление журналами, такие как Data-dog и Sentry, могут сэкономить много времени и денег при возникновении проблем в производственной среде.
Чтобы использовать ErrorBoundary в своем приложении, просто оберните компоненты или части вашего приложения, которые вы хотите защитить, с помощью компонента ErrorBoundary.

Таким образом, React ErrorBoundary является важным инструментом для любого инженера, создающего сложные приложения React. Его способность перехватывать ошибки, отображать резервный пользовательский интерфейс и регистрировать ошибки в API делает его неотъемлемой частью стратегии обработки ошибок вашего приложения. Используя ErrorBoundary, вы можете повысить надежность и стабильность своего приложения, а также обеспечить лучший пользовательский интерфейс для своих пользователей.
Давайте завершим это
В этом посте мы рассмотрели некоторые важные концепции React, такие как компоненты React.lazy, React.Suspense и ErrorBoundary. Независимо от того, являетесь ли вы новичком или опытным разработчиком React, всегда есть чему поучиться, и я призываю вас продолжать изучать и экспериментировать с этой структурой.
Спасибо, что читаете 💜