TGViewer
Андрей Марченко Dev заметки Андрей Марченко Dev заметки @andrey_marchenko_notes · 1.32K subscribers
Post #22 3.11K
Сегодня я наткнулся на дискуссию вокруг Effector https://habr.com/ru/companies/vk/articles/839632/, когда одна из команд VK опубликовала пост с критикой и объяснением, почему они отказываются от этой библиотеки. Я следил за Effector с 2019 года и всегда считал, что он сложен и делает слишком большой акцент на управлении состоянием.

Мой прошлый подход

Мне больше нравился подход с минимальным использованием глобального состояния и применением библиотек типа react-query, SWR, Apollo или Relay, которые берут на себя работу с загрузкой и обновлением данных. В этом случае менеджеры состояния используются только для хранения общих, глобальных данных, которых обычно не так много в большинстве приложений.

Этот подход повлиял на разработку фреймворка Tramvai, над которым я работал. Вот что было внутри:

- Простой менеджер состояния https://tramvai.dev/docs/features/child-app/state-management/ , похожий на Redux, но без глобальных обновлений при каждом изменении.
- React Query для загрузки данных https://tramvai.dev/docs/features/data-fetching/react-query , который полностью отвечал за это, причем данные с API не хранились в менеджере состояния.
- Для SSR использовались глобальные экшены https://tramvai.dev/docs/features/data-fetching/action : для каждой страницы регистрировался набор промисов с действиями, которые нужно было выполнить перед рендерингом страницы.

На этот момент я думал, что это оптимальный подход в React. Но в свое время я не учитывал особенности React, так как React Suspense были чем-то новым на это время и я просто не думал в таких категориях.

Новый взгляд

После перехода в новую компанию я увидел иной подход, основанный на Relay, который активно использует возможности React и при этом значительно упрощает схему, использованную в Tramvai. Relay — это клиент для GraphQL, позволяющий декларативно описывать необходимые данные для компонентов и связывать их между родительскими и дочерними элементами.

Ключевые улучшения:
- Замена глобальных экшенов: Вместо ручного прописывания экшенов используется useFragment https://relay.dev/docs/api-reference/use-fragment/ , который описывает набор данных, необходимых для текущего компонента. При подключении компонента родителем нужно связать необходимость загрузки этих данных https://relay.dev/docs/guided-tour/rendering/fragments/#composing-fragments , что повторяется на всех уровнях, формируя полную цепочку необходимых данных для страницы.
- Использование React Suspense: Этот подход позволяет улучшить визуальную производительность, загружая только необходимые данные. Появляется возможность пометить данные как необязательные для блокирующей загрузки, используя React.Suspense для отображения скелетонов на месте еще не загруженных компонентов.

Как это можно применить к Tramvai

Применяя эти концепции к Tramvai, можно было бы:
- Позволить каждому компоненту описывать необходимые данные для рендеринга. При этом без использования GraphQL, а как необходимые react-query которые необходимы для отрисовки компоненты, дальше это можно дедублицировать
- Связывать эти данные по цепочке к определению роута, просто лист промисов/query
- При переходе на страницу выполнять список промисов/query, которые нужно выполнить для страницы. При этом ожидая только блокирующие данные
- Использовать React Suspense для компонентов, данные которых еще не загружены. Все это автоматически, на основе информации, был ли выполнен query ранее


Преимущества нового подхода:
- Улучшенная производительность: Пользователь видит плавный переход между страницами, где новая страница уже отрендерена с данными для первого экрана, а остальное догружается в фоне.
- Упрощение организации кода: Разработчику не нужно думать о связи с SSR и последующей загрузке. Он просто определяет необходимые компоненту данные, а остальное происходит автоматически.


В итоге, я считаю, что этот способ оптимален для SSR React-приложений, обеспечивая баланс между производительностью и удобством разработки, а так-же открывает дверь к Server components. А так-же убирает большую часть сложности с State manager для большинства сайтов.
  • 👍 17
  • ❤ 5
  • 🥴 2
More from @andrey_marchenko_notes
  1. Sep 4, 2026Выше требования по коммуникации Это то, что меня особенно удивило. Уровень коммуникации у…
  2. Sep 4, 2026Promotion сильно зависит от команды и проекта Promotion сильно зависит от того, в какой ко…
  3. Sep 4, 2026Требования стандартизированы Promotion хорошо описаны, и у людей вокруг есть понимание, чт…
  4. Sep 4, 2026Получил повышение с Senior (IC5) до Staff (IC6) уровня после 2 лет работы в FAANG. До этог…
  5. May 15, 2026Так и появились интересные особенности: * Работа с React/React Native/Relay-разработчиками…
  6. May 15, 2026Давно не писал в канал. 13 мая исполнилось 2 года, как я работаю в Meta и работаю над Ques…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →