All streams
Search
Write a publication
Pull to refresh
63
0
Евгений Лабутин @LabEG

Senior Typescript and C# Developer

Send message

Тоже встречал такую проблему, сложные запросы вешали сервер по нагрузке. Кучка маленьких рестов оказались много эффективнее.

А как выглядит описание моделей для мобильных клиентов? На каждый кастомный квери запрос пишется кастомная модель?

https://github.com/LabEG/reca - тот же mobx, со встроенным DI и удобным коннектором к вьюхе. Уже больше года работает в энтерпрайзных проектах без нареканий.

Вы видимо путаете Xamarin и Xamarin Forms.

Xamarin это набор компиляторов. Сейчас занимает долю 50% всех мобильных 3D игр. Ведь Unity3D работают именно на нем. Ближайшие конкуренты юнити тоже. В обычных приложениях он тоже отлично себя проявил в таких компаниях как боинг, аеробус и банках.

Xamarin Forms это кроссплатформенный фреймворк для интерфейса. Вот с ним действительно было все плохо. Но Майкрософт его выкупила вместе с Xamarin, переписала, переименовала в MAUI и вот вот он выйдет в свет.

Таким образом Xamarin не конкурирует с RN и FL, он конкурирует с нативными языками Kotlin/Swift. А с RN и FL будет конкурировать MAUI (бывший Xamarin Forms).

Например стриминг с камеры на свой сервер с нужными параметрами. Реализуется только нативно через камера апи 2.

Никакие фоновые процессы не заменят простоту, гибкость и удоство шарпового многопоточного async/await.

На самом деле крайне не корректно сравнивать Xamarin с RN и FL. Xamarin это платформа нативной разработки. С многопоточностью и прямым доступом к API операционной системы. У RN и FL надо писать нативные прослойки для прямого доступа к API операционок, а многопоточность в принципе отсутствует из-за скриптовой природы движков. Dart и V8 близкие родственники.

А если уж и добавлять в сравнение то MAUI. Это перезапуск фреймворка Xamarin Forms. Который позволит писать единый интерфейс + плюшки Xamarin.

Сам выбираю React Native для мелочевок, т.к. активно переиспользую код с вебом и Xamarin для чего то серьезного. Во flutter я ни код переиспользовать не могу, ни нативных плюшек нет.

Клиент сможет пользоваться всем, кроме авторизованной зоны.

Однако многопоточная обработка с обменом сообщениями между потоками на Go пишется быстрее и получается лаконичнее. 

А можно поподробнее про практическую часть этого утверждения? По собственному опыту современный шарп выстроен таким образом что тебе в принципе нету необходимости заниматься перегонкой данных между потоками, там либо потоки так организуются что этого не требуется вовсе в 99% случаев, либо используются конкурентные коллекции которые решают оставшийся 1% случаев.

По умолчанию все методы являются computed, если на них нету декоратора @notRedraw. Функцию сравнения состояний делегирована механизму перерисовки реакта.

Задача совсем не типовая, особенно с учетом что в 2022 году редактор и превью объединены. Хабр тому пример.

Но да ладно, два примера решения задачи.

1. Они имеют связь родитель-ребенок:

export const ArticleEditPage = (): JSX.Element => {
    const store = useStore(ArticleStore);

    return (
        <div>
            ...
            <WYSIWYGEditor onChange={store.handleArticleChange} />
            <WYSIWYGPreview article={store.article} />
            ...
            <Button onClick={store.handleSaveArticle}>
                Сохранить
            </Button>
        </div>
    );
}

2. Компоненты расположены очень далеко:

// Компонент редактор
export class WYSIWYGEditorStore extends AutoStore {

    public constructor (
        private readonly eventBusService: EventBusService
    ) {
        super();
    }

    public handleArticleChange(state: ArticleState): void {
        this.eventBusService.dispatch(BusEvent.ARTICLE_CHANGE, state);
    }
}

// Компонент превью
export class WYSIWYGPreviewStore extends AutoStore {

    public constructor (
        private readonly eventBusService: EventBusService
    ) {
        super();
    }

    public activate (): void {
        this.eventBusService.addEventListener(BusEvent.ARTICLE_CHANGE, this.processArticleState);
    }

    public dispose (): void {
        this.eventBusService.removeEventListener(BusEvent.ARTICLE_CHANGE, this.processArticleState);
    }

    private processArticleState (state: ArticleState): void {
        // apply new state
    }

}

Вместо EventBus можно использовать что угодно Observer, RxJS, MobX, React Context, Redux... но почему конкретно мне нравится именно EventBus.

Преимущества:

  1. Позволяет обмениваться состояниями между разными React приложениями на одной странице, с разными рутами, без провайдеров. Актуально для микрофронтов.

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

  3. Обменивание состоянием не перерисовывает все дерево как в случаях с Контекстом.

  4. Умершие компоненты перестают потреблять память на состояния.

  5. Паттерн в целом хорошо себя показал на бекенде на микросервисах. Тут по аналогии каждый компонент это независимое приложение микрофронт и общаются они также.

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

ReCA не использует аналог Zone.JS и манкипатчинга, не использует обработку состояний, не использует глобальный Reaction Runtime.

Вместо этого ловится события вызова логики стора, все сторы независимы, происходит только локальное обновление компонента.

Ничего общего с ченж детектором. Все гораздо проще и быстрее.

Это эффективно поскольку данные для мертвых компонентов не потребляют память, а следовательно и электричество. Нету компонента, нету стора, нету потребления памяти.

Случаи с общими данными между сторами решаются несколькими приемами:

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

  • Код организуется согласно концепции атомарного дизайна, который решает проблему как слишком крупных, так и слишком мелких компонентов.

  • После чего остается очень мало связанных компонентов и данных, вот для них уже используются сервисы, евент басы, обсерверы, контексты или что то свое. Лично я предпочитаю евент бас, как самое практичное решение.

Соответственно данные по дереву прокидываются только в рамках родитель-ребенок и к лишним перерисовкам не приводит.

Во всех случаях нет. Поскольку изменения пересчитываются мгновенно, а с задержкой только перерисовка. Это примерно как в компьютерных играх, видеокарта может считать 200 кадров в секунду, но ограничивают только на 60 (по частоте монитора), что бы она лишнее электричество не потребляла. В ReCA примерно тот же подход.

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

Но в этой либо не все вписывается в идеологию той статьи. В частности пункты Watch Dupes написаны для настоящей реактивности, а не то что в реакте. ReCA работает на событиях от пользователя, но он не рассылает изменения подписчикам, а использует механизм отрисовки реакта. Dupes аналогично, сама ReCA не занимается сравнением состояния, этим так же занимается механизм отрисовки реакта.

В целом в той статье упор идет на Mono Reaction Runtime. В ReCA же используются микро реакции с микро сторами, фактически каждый компонент является независимым микро приложением, за счет чего идеально подходит для микро фронтендов.

Я сыграл в твою игру по твоим правилам. К сожалению новый редактор хабры не может в таблицы, поэтому так.

Style
?✅

Watch
?❌ Вызываются не все подписчики

Dupes
?‍❌ Equality перекладывается на React

Origin
?✅

Tonus
?❌

Order
?❌

Flow
?✅

Error
?❌ Обработка ошибок на стороне пользователя и фреймворка

Cycle
?✅ Сторы не могут попасть в цикл, ибо изолированы, в крайнем случае словится лимит стека

Depth
?✅

Atomic
?❌

Extern
?✅

Подход действительно похож и является скорее логическим развитием чем аналогом. И тем кто работал на MobX будет проще всего переключиться на Reca. MobX так же имеет зачатки так называемой чистой архитектуры, но он почему то остановился на сторах, и не стал идти дальше.

В частности он не отвечает на вопрос "А где хранить пере используемую в сторах логику?" и имеет проблему с жизненным циклом. В Reca все эти проблемы решены.

А именно:

  • Встроен DI, теперь переиспользуемую логику можно выносить в сервисы, фронтам может быть знакомо по Angular и NestJS,

  • Сильно упрощен механизм инъекции стора в компоненты,

  • Лишен проблем с жизненным циклом,

  • Улучшенный механизм перерисовки, что хорошо сказывается на производительности на слабых устройствах,

  • Легко кастомизируется, можно легко создать свою реализацию стора отнаследовав от базового стора.

До перехода на функциональные компоненты так и делали. Но сейчас все же используем хуки. Причины:

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

  • Про хуки знает каждый джун разработчик, они подробно описаны в документации,

  • В хуке скрыта логика перерисовки компонента при ресайзе окна и ее легко реюзать в компонентах, не нужно наследование и композиция.

В итоге сильно понижаем порог входа не жертвую качеством.

На вопрос ниже отвечу вечером как буду посвободнее.

А наследование работает? Можно сделать второй компонент отнаследовав от первого и добавив логики? )

А хуки есть?) С хуками например очень просто делать такие вещи:

export const Product = (): JSX.Element => {
    const store = useStore(SomeStore);
    const {isSmallScreen} = useScreenSize();

    return (
        <Swiper
            slidesPerView={isSmallScreen ? "auto" : 2}
            spaceBetween={isSmallScreen ? "20" : "40"}
            updateOnWindowResize
        >
            ...
        </Swiper>
    )
};

Изначально была проверка для нескольких компонентов, в т.ч. для использования в css. И в этом компонента она сохранилась как есть.

Насчет поменять ли на picture что бы решал сам браузер - не уверен что в этом есть смысл. В доме будет больше не нужных элементов и по стилям оно не всегда обратно совместимо с img.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity

Specialization

Fullstack Developer
Lead
From 750,000 ₽