В React 18 обновится подход к SSR
Используя API <Suspense> можно отделить «тяжелые» участки вашего приложения и ускорить отдачу серверного кода в клиент. Возможно это, если использовать новое API pipeToNodeWritable.
Но обо всем по порядку. Что такое SSR?
При загрузке сайта без SSR, пользователь сначала видит белую страницу, и только после загрузки бандла с JS начнет отображаться UI, и пользователь может с ним работать.
Если есть SSR, то при загрузке сайта пользователь практически сразу видит UI, но пользователь никак не может с ним взаимодействовать: обработчики событий еще не подключены. Необходимо подождать загрузки JS бандлов, после чего React соберет в памяти дерево компонентов и подключит к существующему HTML логику приложения. Это называется гидратация.
Однозначным плюсом SSR является то, что пользователи с более медленным интернетом смогут быстрее увидеть UI, однако показатель TTI (Time to Interactive) лучше не станет.
Какие минусы SSR в React 17?
- Необходимо дождаться загрузки данных. При получение страницы с сервера, необходимо чтобы сервер имел все данные для компонентов для их рендера. То есть серверу необходимо сходить в API, получить данные и передать их компоненту, после чего будет собран HTML и передан клиенту.
- Необходимо дождаться загрузки всех JS бандлов. Это означает, что если есть модуль, с сложной логикой внутри и большим количеством кода, то на клиенте необходимо дождаться загрузки бандла с кодом этого модуля. Это происходит из за того, что гидратация проходит в один этап, поэтому все бандлы с кодом должны быть загружены, иначе если для HTML кода нет связанного с ним загруженного кода из бандла, то он будет удален из HTML во время гидратации.
- Для взаимодействия с UI необходимо дождаться окончания гидратации. Этот минус связан с особенностью гидратации, которая проходит дерево один раз. Это значит, что если есть какой компонент, со сложной логикой рендера, то это может стать узким горлышком на этапе гидратации. Пользователь не сможет взаимодействовать с UI, пока гидратация не будет закончена полностью.
Используя API <Suspense> можно отделить «тяжелые» участки вашего приложения и ускорить отдачу серверного кода в клиент. Возможно это, если использовать новое API pipeToNodeWritable.
Но обо всем по порядку. Что такое SSR?
При загрузке сайта без SSR, пользователь сначала видит белую страницу, и только после загрузки бандла с JS начнет отображаться UI, и пользователь может с ним работать.
Если есть SSR, то при загрузке сайта пользователь практически сразу видит UI, но пользователь никак не может с ним взаимодействовать: обработчики событий еще не подключены. Необходимо подождать загрузки JS бандлов, после чего React соберет в памяти дерево компонентов и подключит к существующему HTML логику приложения. Это называется гидратация.
Однозначным плюсом SSR является то, что пользователи с более медленным интернетом смогут быстрее увидеть UI, однако показатель TTI (Time to Interactive) лучше не станет.
Какие минусы SSR в React 17?
- Необходимо дождаться загрузки данных. При получение страницы с сервера, необходимо чтобы сервер имел все данные для компонентов для их рендера. То есть серверу необходимо сходить в API, получить данные и передать их компоненту, после чего будет собран HTML и передан клиенту.
- Необходимо дождаться загрузки всех JS бандлов. Это означает, что если есть модуль, с сложной логикой внутри и большим количеством кода, то на клиенте необходимо дождаться загрузки бандла с кодом этого модуля. Это происходит из за того, что гидратация проходит в один этап, поэтому все бандлы с кодом должны быть загружены, иначе если для HTML кода нет связанного с ним загруженного кода из бандла, то он будет удален из HTML во время гидратации.
- Для взаимодействия с UI необходимо дождаться окончания гидратации. Этот минус связан с особенностью гидратации, которая проходит дерево один раз. Это значит, что если есть какой компонент, со сложной логикой рендера, то это может стать узким горлышком на этапе гидратации. Пользователь не сможет взаимодействовать с UI, пока гидратация не будет закончена полностью.
👍2
Как можно исправить существующие минусы?
Рассмотрим текущий флоу SSR: запрос данных (сервер) -> рендер HTML (сервер) -> загрузка кода (клиент) -> гидратация (клиент). Флоу выполняется по шагам, ожидая завершения предыдущего, что не очень эффективно. Этот флоу выполняется для всего приложения, т.е. если некоторые его компоненты «тормозят» на одном из шагов, то тормозит весь флоу. Решением этой проблемы является разбитие флоу приложения на несколько частей, по компонентам, вместо целого приложения. Кстати, эта идея не нова, и уже использовалась в фреймворке Marko для реализации данного паттерна.
Для разбития приложения на части используется <Suspense>. Вот что можно делать с его помощью:
- Потоковая отправка HTML. Позволяет не ждать загрузки всех данных на сервере для рендера, отправить HTML клиенту, а как только данные будут получены, отрендерить на сервере, и отправить на клиент. Например, есть блок с комментариями, и мы можем асинхронно загружать по ним информацию и отдавать HTML, а когда комментарии будут получены, отрендерить их и отправить клиенту в конце HTML документа, выглядеть это будет примерно так:
- Выборочная гидратация на клиенте. Если у вас есть компоненты со сложной логикой, то обернув их в Suspense, React при гидратации компонентов не будет блокировать UI. Гидратация будет происходить во время простоя браузера, поэтому пользовательские события будут обработаны сразу. При этом, если на клиенте сразу несколько разных компонентов ожидают гидратации, то их гидратация будет происходить с учетом пользовательских событий. Например, есть блок комментариев, который находится на очереди гидратации, и если пользователь сделал клик в пределах этого компонента, то React запомнит этот клик и сделает гидратацию комментариев в первую очередь, после чего «воспроизведет» клик заново (dispatch события).
Более подробно, с иллюстрациями, в теме на Github.
Рассмотрим текущий флоу SSR: запрос данных (сервер) -> рендер HTML (сервер) -> загрузка кода (клиент) -> гидратация (клиент). Флоу выполняется по шагам, ожидая завершения предыдущего, что не очень эффективно. Этот флоу выполняется для всего приложения, т.е. если некоторые его компоненты «тормозят» на одном из шагов, то тормозит весь флоу. Решением этой проблемы является разбитие флоу приложения на несколько частей, по компонентам, вместо целого приложения. Кстати, эта идея не нова, и уже использовалась в фреймворке Marko для реализации данного паттерна.
Для разбития приложения на части используется <Suspense>. Вот что можно делать с его помощью:
- Потоковая отправка HTML. Позволяет не ждать загрузки всех данных на сервере для рендера, отправить HTML клиенту, а как только данные будут получены, отрендерить на сервере, и отправить на клиент. Например, есть блок с комментариями, и мы можем асинхронно загружать по ним информацию и отдавать HTML, а когда комментарии будут получены, отрендерить их и отправить клиенту в конце HTML документа, выглядеть это будет примерно так:
<div hidden id="comments">
<!-- Comments -->
<p>First comment</p>
<p>Second comment</p>
</div>
<noscript>
// Примерная реализация
document.getElementById('sections-spinner').replaceChildren(
document.getElementById('comments')
);
</noscript>
- Выборочная гидратация на клиенте. Если у вас есть компоненты со сложной логикой, то обернув их в Suspense, React при гидратации компонентов не будет блокировать UI. Гидратация будет происходить во время простоя браузера, поэтому пользовательские события будут обработаны сразу. При этом, если на клиенте сразу несколько разных компонентов ожидают гидратации, то их гидратация будет происходить с учетом пользовательских событий. Например, есть блок комментариев, который находится на очереди гидратации, и если пользователь сделал клик в пределах этого компонента, то React запомнит этот клик и сделает гидратацию комментариев в первую очередь, после чего «воспроизведет» клик заново (dispatch события).
Более подробно, с иллюстрациями, в теме на Github.
Изменения <Suspense> в React 18
Рассмотрим список изменений, которые будут в React 18.
Изменения в текущем поведение <Suspense>
- Вызов эффектов у компонентов внутри <Suspense> будет запускаться только после того, как компонент будет отображен пользователю. Раньше это происходило слишком рано, еще в моменте когда отображался плейсхолдер компонента.
- Повторный запуск эффекта useLayoutEffect при появление и исчезании компонента. Если компонент, который был отображен пользователю уходит в «ожидание», и исчезает из видимости, то внутри компонента никак нельзя было узнать об этом. Сейчас при появление компонента будет вызываться эффект useLayoutEffect, а при исчезание вызываться возвращаемая им функция (похож на componentWillUnmount).
- <Suspense> не будет вызывать ошибок на стороне сервера. Раньше нельзя было использовать <Suspense> на стороне сервера, теперь будет можно.
Новые фичи <Suspense>
- startTransition внутри <Suspense> предотвратит исчезание компонента, даже если он переходит в режим «ожидания». Это позволит легко реализовать паттерн «показа старых данных при загрузке новых».
- Встроенный тротлинг в <Suspense>. React будет сам тротлить показ вложенных фолбеков <Suspense>, поэтому UI не будет постоянно дергаться и показываться плейсхолдер при быстрых обновлениях данных.
- Использование <Suspense> и lazy компонентов на сервере. Вместе с pipeToNodeWritable позволяет использовать потоковый стриминг HTML и частичную гидратацию компонентов на клиенте.
<Suspense> и получение данных
Выше приведенные изменения являются фундаментальными архитектурными изменения в <Suspense>, однако они не решают проблему получения данных внутри Suspense. Скорее всего, после 18 версии выйдут минорные версии, которые добавят следующий функционал:
- Библиотека ввода/вывода типа react-fetch, которая предоставит простой способ получения данных внутри <Suspense>.
- Встроенный Suspense <Cache>, который будет основным рекомендованным способом интеграции с <Suspense> для сторонних библиотек получения данных (react-fetch использует его).
- Серверные компоненты будет рекомендованным способом для получения данных в <Suspense>, который хорошо масштабируется и интегрируется с react-fetch и другими сторонними библиотеками.
- чистая и понятная документация для сторонних библиотек получения данных для интеграции с Suspense.
https://github.com/reactwg/react-18/discussions/47
Рассмотрим список изменений, которые будут в React 18.
Изменения в текущем поведение <Suspense>
- Вызов эффектов у компонентов внутри <Suspense> будет запускаться только после того, как компонент будет отображен пользователю. Раньше это происходило слишком рано, еще в моменте когда отображался плейсхолдер компонента.
- Повторный запуск эффекта useLayoutEffect при появление и исчезании компонента. Если компонент, который был отображен пользователю уходит в «ожидание», и исчезает из видимости, то внутри компонента никак нельзя было узнать об этом. Сейчас при появление компонента будет вызываться эффект useLayoutEffect, а при исчезание вызываться возвращаемая им функция (похож на componentWillUnmount).
- <Suspense> не будет вызывать ошибок на стороне сервера. Раньше нельзя было использовать <Suspense> на стороне сервера, теперь будет можно.
Новые фичи <Suspense>
- startTransition внутри <Suspense> предотвратит исчезание компонента, даже если он переходит в режим «ожидания». Это позволит легко реализовать паттерн «показа старых данных при загрузке новых».
- Встроенный тротлинг в <Suspense>. React будет сам тротлить показ вложенных фолбеков <Suspense>, поэтому UI не будет постоянно дергаться и показываться плейсхолдер при быстрых обновлениях данных.
- Использование <Suspense> и lazy компонентов на сервере. Вместе с pipeToNodeWritable позволяет использовать потоковый стриминг HTML и частичную гидратацию компонентов на клиенте.
<Suspense> и получение данных
Выше приведенные изменения являются фундаментальными архитектурными изменения в <Suspense>, однако они не решают проблему получения данных внутри Suspense. Скорее всего, после 18 версии выйдут минорные версии, которые добавят следующий функционал:
- Библиотека ввода/вывода типа react-fetch, которая предоставит простой способ получения данных внутри <Suspense>.
- Встроенный Suspense <Cache>, который будет основным рекомендованным способом интеграции с <Suspense> для сторонних библиотек получения данных (react-fetch использует его).
- Серверные компоненты будет рекомендованным способом для получения данных в <Suspense>, который хорошо масштабируется и интегрируется с react-fetch и другими сторонними библиотеками.
- чистая и понятная документация для сторонних библиотек получения данных для интеграции с Suspense.
https://github.com/reactwg/react-18/discussions/47
GitHub
Behavioral changes to Suspense in React 18 · reactwg/react-18 · Discussion #7
Overview We added basic support for Suspense in React 16.x. But it wasn’t full support for Suspense — it doesn’t do all the things we’ve shown off in our demos, like delayed transitions (i.e. waiti...
Как сократить время загрузки React приложения на 70%.
Основная причина долгой загрузки React приложений это большое количество компонентов в одном бандле. Для решения этой проблемы React предлагает использовать code-splitting и lazy loading.
Код-сплит на роутах решает половину проблем, однако бывает, что размер бандла все равно остается большим.
Например есть страница дашборда, где есть переключаемые табы и компоненты внутри них. При загрузке страницы активен только первый таб, остальные не видны. Автор статьи предлагает использовать код-сплит компонентов внутри роута, т.е. включить ленивую загрузку компонентов по запросу, используя <Suspense>.
Таким образом, автору статьи удалось уменьшить размер загружаемого бандла почти в 2.5 раза и сократить время загрузки сайта.
https://dev.to/nilanth/how-to-reduce-react-app-loading-time-by-70-1kmm
Основная причина долгой загрузки React приложений это большое количество компонентов в одном бандле. Для решения этой проблемы React предлагает использовать code-splitting и lazy loading.
Код-сплит на роутах решает половину проблем, однако бывает, что размер бандла все равно остается большим.
Например есть страница дашборда, где есть переключаемые табы и компоненты внутри них. При загрузке страницы активен только первый таб, остальные не видны. Автор статьи предлагает использовать код-сплит компонентов внутри роута, т.е. включить ленивую загрузку компонентов по запросу, используя <Suspense>.
Таким образом, автору статьи удалось уменьшить размер загружаемого бандла почти в 2.5 раза и сократить время загрузки сайта.
https://dev.to/nilanth/how-to-reduce-react-app-loading-time-by-70-1kmm
DEV Community
How to Reduce React App Loading Time By 70%
Steps to decrease your React app initial loading time using code splitting. We build large-scale...
Что такое «разрыв» интерфейса?
Термин «разрыв» например используется в видео, и означает когда на экране отображаются разные кадры, видео выглядит «глючным». В пользовательском интерфейсе «разрыв» означает, что мы показываем разные значения для одного и того же состояния.
JavaScript - однопоточный, поэтому разработчики в основном не сталкиваются с такого рода проблемами. Однако, в React 18 был добавлен конкурентный рендеринг, и используя API startTransition или Suspense, можно «выстрелить себе в ногу», т.к. они позволяют ставить работу на паузу и брать более срочные задачи на выполнение.
Термин «разрыв» например используется в видео, и означает когда на экране отображаются разные кадры, видео выглядит «глючным». В пользовательском интерфейсе «разрыв» означает, что мы показываем разные значения для одного и того же состояния.
JavaScript - однопоточный, поэтому разработчики в основном не сталкиваются с такого рода проблемами. Однако, в React 18 был добавлен конкурентный рендеринг, и используя API startTransition или Suspense, можно «выстрелить себе в ногу», т.к. они позволяют ставить работу на паузу и брать более срочные задачи на выполнение.
Рассмотрим пример работы React приложения без использования конкурентного рендеринга.
На картинке мы рендерим дерево React компонентов, один за другим. Каждый компонент рендерится по очереди, React не останавливает работу рендера, поэтому все компоненты получают одинаковое значение стора. После рендера всех компонентов, React освобождается и на 4ом шаге может изменить состояние стора
На картинке мы рендерим дерево React компонентов, один за другим. Каждый компонент рендерится по очереди, React не останавливает работу рендера, поэтому все компоненты получают одинаковое значение стора. После рендера всех компонентов, React освобождается и на 4ом шаге может изменить состояние стора
Пример работы React приложения с использованием конкурентного рендеринга.
В основном работа конкурентного ренедеринга не вызывает никаких проблем с консистентностью отображения данных, но бывают граничные случаи, когда это возможно.
Мы начинаем рендер дерева React компонентов, и рендерим первый компонент. Т.к. мы используем конкурентный рендеринг, React может остановить работу по рендеру компонентов, даже когда она не закончена. Это большой плюс к отзывчивости интерфейса, пользователь может сделать клик по кнопке и сразу увидеть результат.
Следствием этого подхода является то, что в результате пользовательского клика (или другой асинхронной работы, например ответ по сети или timeout) может измениться значение стора, которое используется компонентами для рендера. Это и есть граничный случай, который может спровоцировать проблемы.
В основном работа конкурентного ренедеринга не вызывает никаких проблем с консистентностью отображения данных, но бывают граничные случаи, когда это возможно.
Мы начинаем рендер дерева React компонентов, и рендерим первый компонент. Т.к. мы используем конкурентный рендеринг, React может остановить работу по рендеру компонентов, даже когда она не закончена. Это большой плюс к отзывчивости интерфейса, пользователь может сделать клик по кнопке и сразу увидеть результат.
Следствием этого подхода является то, что в результате пользовательского клика (или другой асинхронной работы, например ответ по сети или timeout) может измениться значение стора, которое используется компонентами для рендера. Это и есть граничный случай, который может спровоцировать проблемы.
На 2ом шаге можно увидеть, что React остановил рендер и изменил значение стора из-за клика пользователя. Проблема в том, что первый компонент отрендерился синим (на момент рендера значение стора было синим), но остальные компоненты при рендере получат текущее значение, которое является красным.
На последнем шаге компоненты, которые раньше всегда были синие, отображаются как микс из синих и красных компонентов. Они отображают два разных значения для одних и тех же данных. Это и есть разрыв интерфейса.
https://github.com/reactwg/react-18/discussions/69
На последнем шаге компоненты, которые раньше всегда были синие, отображаются как микс из синих и красных компонентов. Они отображают два разных значения для одних и тех же данных. Это и есть разрыв интерфейса.
https://github.com/reactwg/react-18/discussions/69
Библиотеки для анимации интерфейсов
- Framer Motion. Поддерживает декларативное описание анимаций, переходы и обработку жестов, серверный рендеринг. Можно управлять анимацией вручную и отслеживать состояние через MotionValues. Позволяет интерполировать значения через хук useTransform. Подробная документация, много готовых примеров. Напоминает библиотеку анимаций для React Native.
- react-spring. Одна из самых популярных библиотек для анимаций в React, содержит большое количество настроек для создания любого вида анимаций. Поддерживает интерполяцию данных, имеет возможность запуска серии зависимых друг от друга анимаций, плавные переходы. Помимо технических характеристик, у библиотеки большое комьюнити.
- React Transition Group. Набор компонентов для управления переходами в приложение. Имеет достаточно простые настройки, позволяет управлять анимацией переключением CSS классов.
- react-animations. Набор анимаций из библиотеки animate.css, может использоваться с любой встраиваемой библиотекой стилей.
- Framer Motion. Поддерживает декларативное описание анимаций, переходы и обработку жестов, серверный рендеринг. Можно управлять анимацией вручную и отслеживать состояние через MotionValues. Позволяет интерполировать значения через хук useTransform. Подробная документация, много готовых примеров. Напоминает библиотеку анимаций для React Native.
- react-spring. Одна из самых популярных библиотек для анимаций в React, содержит большое количество настроек для создания любого вида анимаций. Поддерживает интерполяцию данных, имеет возможность запуска серии зависимых друг от друга анимаций, плавные переходы. Помимо технических характеристик, у библиотеки большое комьюнити.
- React Transition Group. Набор компонентов для управления переходами в приложение. Имеет достаточно простые настройки, позволяет управлять анимацией переключением CSS классов.
- react-animations. Набор анимаций из библиотеки animate.css, может использоваться с любой встраиваемой библиотекой стилей.
Material UI обновилась до 5 версии
- Новый бренд: Material UI теперь будет называться MUI.
- В новой версии был сделан упор на улучшение кастомизации компонентов. Одно из больших изменений - это возможность выбора библиотеки для работы со стилями. Теперь по умолчанию, вместо JSS используется Emotion. Так же можно выбрать styled-components или остаться на JSS, либо выбрать любую другую библиотеку, если есть адаптер.
- Компоненты без стилей. Добавили набор хуков, которые реализуют логику базовых компонент (кнопки, автокомплит, слайдеры), с помощью которых можно самостоятельно собирать компоненты, со своими стилями. Позволяет хорошо сэкономить время при разработке своей дизайн-системы.
- Мигрировали свои тесты с Enzyme на Testing Library.
https://mui.com/blog/mui-core-v5/
- Новый бренд: Material UI теперь будет называться MUI.
- В новой версии был сделан упор на улучшение кастомизации компонентов. Одно из больших изменений - это возможность выбора библиотеки для работы со стилями. Теперь по умолчанию, вместо JSS используется Emotion. Так же можно выбрать styled-components или остаться на JSS, либо выбрать любую другую библиотеку, если есть адаптер.
- Компоненты без стилей. Добавили набор хуков, которые реализуют логику базовых компонент (кнопки, автокомплит, слайдеры), с помощью которых можно самостоятельно собирать компоненты, со своими стилями. Позволяет хорошо сэкономить время при разработке своей дизайн-системы.
- Мигрировали свои тесты с Enzyme на Testing Library.
https://mui.com/blog/mui-core-v5/
Универсальные компоненты
Если вы задумывались о разработке собственной библиотеки компонентов, то прежде чем начать её делать, стоит посмотреть в сторону библиотек универсальных компонентов. Существуют несколько таких библиотек. Разработчики из Adobe создали React Aria, MUI в 5 версии добавили unstyled components, в Яндексе начали заниматься разработкой универсальной дизайн-системы.
Библиотеки предоставляют коллекцию кастомных хуков для реализации базовых примитивов интерфейса. Хуки инкапсулируют в себе логику поведения элемента интерфейса и возвращают необходимые пропсы для отображения, учитывая правила доступности A11Y. Разработчикам, использующим данную библиотеку, нужно сфокусироваться только на дизайне для компонентов.
Хорошая возможность для быстрой разработки своей дизайн-системы.
Если вы задумывались о разработке собственной библиотеки компонентов, то прежде чем начать её делать, стоит посмотреть в сторону библиотек универсальных компонентов. Существуют несколько таких библиотек. Разработчики из Adobe создали React Aria, MUI в 5 версии добавили unstyled components, в Яндексе начали заниматься разработкой универсальной дизайн-системы.
Библиотеки предоставляют коллекцию кастомных хуков для реализации базовых примитивов интерфейса. Хуки инкапсулируют в себе логику поведения элемента интерфейса и возвращают необходимые пропсы для отображения, учитывая правила доступности A11Y. Разработчикам, использующим данную библиотеку, нужно сфокусироваться только на дизайне для компонентов.
Хорошая возможность для быстрой разработки своей дизайн-системы.
Adobe
React Aria
Craft world-class accessible components with custom styles.
Реальный пример работы startTransition
Ricky Hanlon показал подробный пример работы API startTransition из React 18, с объяснением работы API и того, как работает приложение в perfomance профиле.
В примере показан слайдер и компонент с «тяжелыми вычислениями», который занимает много времени для рендера, особенно на слабых устройствах. После изменения значения слайдера происходил ререндер тяжелого компонента. Самый оптимальный вариант рендера тяжелого компонента в React 17 через debounce, т.е. откладывая рендер на изменения слайдера.
В React 18 изменение значения слайдера достаточно обернуть в startTransition, и React уже сам выполнит эффективный рендер компонента. После рендера изменения значения слайдера, React рендерит transition результатов. Так как в этом изменение включен параллельный рендеринг, React делает три новые вещи:
- Yielding: каждые 5 мс React ставит работу рендера на паузу, чтобы дать браузеру сделать другую работу, например запустить промисы.
- Прерывание: React ставит рендер на паузу, если необходимо отрендерить более приоритетный компонент, например ползунок слайдера из примера.
- Отбрасывание старых результатов: когда React начинает рендерить после прерывания, то он отбрасывает старый компонент и рендерит новый.
https://github.com/reactwg/react-18/discussions/65
Ricky Hanlon показал подробный пример работы API startTransition из React 18, с объяснением работы API и того, как работает приложение в perfomance профиле.
В примере показан слайдер и компонент с «тяжелыми вычислениями», который занимает много времени для рендера, особенно на слабых устройствах. После изменения значения слайдера происходил ререндер тяжелого компонента. Самый оптимальный вариант рендера тяжелого компонента в React 17 через debounce, т.е. откладывая рендер на изменения слайдера.
В React 18 изменение значения слайдера достаточно обернуть в startTransition, и React уже сам выполнит эффективный рендер компонента. После рендера изменения значения слайдера, React рендерит transition результатов. Так как в этом изменение включен параллельный рендеринг, React делает три новые вещи:
- Yielding: каждые 5 мс React ставит работу рендера на паузу, чтобы дать браузеру сделать другую работу, например запустить промисы.
- Прерывание: React ставит рендер на паузу, если необходимо отрендерить более приоритетный компонент, например ползунок слайдера из примера.
- Отбрасывание старых результатов: когда React начинает рендерить после прерывания, то он отбрасывает старый компонент и рендерит новый.
https://github.com/reactwg/react-18/discussions/65
GitHub
Real world example: adding startTransition for slow renders · reactwg react-18 · Discussion #65
In React 18 we announced a new startTransition API and shared a high-level overview of the problem it solves. In this post, we’re going to dive into a real-world example of speeding up a slow updat...
Redux Toolkit на замену Redux
Если вы планируете использовать Redux в проекте, то рекомендую присмотреться к Redux Toolkit. Инструмент решает основные боли Redux, такие как лишний бойлерплейт и сложная настройка, а так же добавляет дополнительный функционал для работы со стором - слайсы.
Слайс представляет собой изолированную часть общего состояния стора, и автоматически генерирует action creators и action типы для соответствующих редьюсеров.
RTK Query - модуль для работы с сетевыми запросами и кэшированием, является частью Redux Toolkit. Возможности инструмента: простое получение и изменение данных, получение состояния запроса, оптимистичные обновления, управление кэшем запросов.
Предоставляет удобное API для создания и настройки запросов, а так же генерирует хуки, инкапсулирующие процесс получения данных, которые используются в компонентах.
Преимущества библиотеки: полностью написана на TypeScript, хорошая документация, большое комьюнити.
https://redux-toolkit.js.org/introduction/getting-started
Если вы планируете использовать Redux в проекте, то рекомендую присмотреться к Redux Toolkit. Инструмент решает основные боли Redux, такие как лишний бойлерплейт и сложная настройка, а так же добавляет дополнительный функционал для работы со стором - слайсы.
Слайс представляет собой изолированную часть общего состояния стора, и автоматически генерирует action creators и action типы для соответствующих редьюсеров.
RTK Query - модуль для работы с сетевыми запросами и кэшированием, является частью Redux Toolkit. Возможности инструмента: простое получение и изменение данных, получение состояния запроса, оптимистичные обновления, управление кэшем запросов.
Предоставляет удобное API для создания и настройки запросов, а так же генерирует хуки, инкапсулирующие процесс получения данных, которые используются в компонентах.
Преимущества библиотеки: полностью написана на TypeScript, хорошая документация, большое комьюнити.
https://redux-toolkit.js.org/introduction/getting-started
redux-toolkit.js.org
Getting Started | Redux Toolkit
Инструменты для отладки React приложений
Если приложение работает медленно, то для поиска причины тормозов можно использовать специальные инструменты:
- React DevTools. Базовый инструмент отладки React приложения. Умеет снимать perfomance профиль приложения, показать какой компонент отрендерился и сколько времени на это потребовалось.
- Why Did You Render (WDYR). Стандартного React DevTools может не хватать, поэтому в процесс отладки можно добавить WDYR. Этот инструмент находит компоненты, рендер которых можно избежать. Например, значением пропса компонента объявляется объект, поэтому этот компонент будет рендерится каждый раз, когда компонент создается. Найденную информацию WDYR отправляет в логи браузера.
- React Render Tracker. Инструмент для отслеживания производительности приложения Романа Дворнова. Умеет отслеживать изменения выбранного компонента, причину рендера, тайминги рендера компонента и его поддерева. Хороший UI, простая установка.
Если приложение работает медленно, то для поиска причины тормозов можно использовать специальные инструменты:
- React DevTools. Базовый инструмент отладки React приложения. Умеет снимать perfomance профиль приложения, показать какой компонент отрендерился и сколько времени на это потребовалось.
- Why Did You Render (WDYR). Стандартного React DevTools может не хватать, поэтому в процесс отладки можно добавить WDYR. Этот инструмент находит компоненты, рендер которых можно избежать. Например, значением пропса компонента объявляется объект, поэтому этот компонент будет рендерится каждый раз, когда компонент создается. Найденную информацию WDYR отправляет в логи браузера.
- React Render Tracker. Инструмент для отслеживания производительности приложения Романа Дворнова. Умеет отслеживать изменения выбранного компонента, причину рендера, тайминги рендера компонента и его поддерева. Хороший UI, простая установка.
Slate.js - настраиваемый текстовый редактор
При разработке библиотеки, автор был вдохновлен Draft.js, Prosemirror и Quill, но его не устраивала монолитная архитектура библиотек, сложность кастомизации и добавления своих элементов, ограничение в создании сложных документов с таблицами и вложенными объектами.
Особенности редактора:
- Кастомизация. Slate.js разработана на плагинах, можно легко расширить текущий функционал библиотеки самостоятельно.
- Слабая схема данных. Не важно с какими данными вы работаете, что упрощает создание более сложных редакторов, чем базовый.
- Вложенная модель документа. Slate.js использует модель документа похожую на DOM и предоставляет стандартные обработчики событий. Это означает, что возможно создание более сложных компонентов, например таблицы.
- Коллективная работа. Модель данных спроектирована таким образом, что позволяет работать коллективно над одним документом, например как в гугл документах. Пример.
https://github.com/ianstormtaylor/slate
При разработке библиотеки, автор был вдохновлен Draft.js, Prosemirror и Quill, но его не устраивала монолитная архитектура библиотек, сложность кастомизации и добавления своих элементов, ограничение в создании сложных документов с таблицами и вложенными объектами.
Особенности редактора:
- Кастомизация. Slate.js разработана на плагинах, можно легко расширить текущий функционал библиотеки самостоятельно.
- Слабая схема данных. Не важно с какими данными вы работаете, что упрощает создание более сложных редакторов, чем базовый.
- Вложенная модель документа. Slate.js использует модель документа похожую на DOM и предоставляет стандартные обработчики событий. Это означает, что возможно создание более сложных компонентов, например таблицы.
- Коллективная работа. Модель данных спроектирована таким образом, что позволяет работать коллективно над одним документом, например как в гугл документах. Пример.
https://github.com/ianstormtaylor/slate
