У меня на проекте была задача при изменении зума карты, отображать в боковом меню список точек которые попадают в зону видимости карты. Так вот этот хук идеально вписался в решение этой задачи, помогая пропускать промежуточные ненужные рендеры, например пока пользователь быстро колесом мыши зумит туда сюда)
@it-sin9k3 ай бұрын
очень крутой кейс!) спасибо что поделились!) интересно только как вы работали с запросами в левом меню, вы их тоже отправляли и отменяли с помощью abort controller при быстром скроле? я име ввиду для draft рендеров
@gtsjdm3 ай бұрын
@@it-sin9k там все было проще, один запрос на все точки при инициализации, точек не так много чуть больше 300. Лаг был именно в сайдбаре, при частых пересчетах самого списка.
@it-sin9k2 ай бұрын
прикольно) спасибо за ответ)
@Ernuna3 ай бұрын
новичкам трудно понять зачем нужен useDeferredValue если можно написать debounce. Разница в том, useDeferredValue будет задерживать значения в зависимости от возможностей железа пользователя. На быстром будет срабатывать быстро а на слабом медленнее подстраиваясь под рендер каждого девайса. Т.е не нужен хардкод таймаута.
@it-sin9k3 ай бұрын
Хорошо сказано!)
@AA-Vezel3 ай бұрын
С другой стороны, uDV будет нагружать машину пользователя, тратить киловатты (эффект масштаба) на пустые обсчеты и тем самым увеличивая углеродный след. Как бы нам зелёные звиздюлей не дали за такую оптимизацию 😂
@Sameyl13 ай бұрын
Ну это и было сказано в видосе) прикольная тема конечно
@CJIu3eHb2 ай бұрын
@@AA-Vezel "Машины должны страдать", и зеленые тоже... :)
@paveludaloff72942 ай бұрын
Там idle callback под капотом?
@bislan-aranyan3 ай бұрын
спасибо за выпуск, очень интересно было послушать, как можно использовать useDeferredValue и что твориться под копотом
@The14Some13 ай бұрын
Автор, ты так и не сделал одно очень важное замечание: Поскольку реакт отбрасывает те рендеры, которые он не успевает, если новые изменения происходят до окончания рендера, то мы увидим следующий рендер только когда поток изменений будет содержать достаточно большую паузу, чтоб ререндер успел успешно завершиться. Эта особенность делает данный подход неприемлемым как раз в тех случаях, о которых ты упомянул, а именно на 3:33. Если поток данных будет продолжаться непрерывно, то может возникнуть ситуация, что на рендер не будет хватать времени вообще никогда. И пользователь вообще не будет видеть обновлений. Правильным решением было бы делать ререндеры по мере их фактической возможности один за другим и не отменять рендеры при появлении новых изменений. При этом данные под каждый рендер-колл брать на момент получения заявки на этот рендер-колл. Как было: каждое изменение порождало свой рендер-колл, и блочило движок до окончания ререндера Как сейчас: каждое изменение порождает новый рендер-колл асинхронно, и если ререндер уже производится, то отменяет устаревший ререндер Как нужно: каждое изменение инвалидирует состояние, что является триггером для создания нового рендер-колла рендер-коллы выполняются в отдельном потоке один за другим, не блоча движок, и нет механизма отмены старого "устаревшего" рендер-колла.
@it-sin9k3 ай бұрын
Они как то рассказывали, что тестировали варианты использования соседних потоков для разгружения основного, но насколько я помню, это слишком медленно работало и отказались
@archibaldstriebendrossel2 ай бұрын
Когда не хватает мощности для отрисовки, у нас есть выбор: рисовать все кадры, но тормозить, или пропускать кадры, но быстро. Debounce и useDeferredValue - про второе. Ваше решение - про первое. Мощности ваше решение не добавляет, т.к. не распараллеливает нагрузку, а выносит её в другой поток. Что, вообще-то, непонятно как сделать. Почему? Это проще понять на практике, чем описать в комментарии. Дальше, если мы не можем вынести значительную часть нагрузки в отдельный поток, значит не можем и распараллелить. Даже если существует способ это сделать, он скорей всего предполагает ухудшение DX и увеличение общей нагрузки на компьютер в обмен на увеличение throughput и незначительное уменьшение latency. А именно latency нас и волнует. С таким раскладом можно потратить много сил и времени на проработку, и получить около бесполезную технологию.
@The14Some12 ай бұрын
@@archibaldstriebendrossel я не предлагал рисовать все кадры, но тормозить. Я предлагал не отменять устаревшие недорисованные кадры, а дорисовывать, и как только кадр отрисован, брать текущее состояние, и начинать рисовать снова. Пока есть заявки на перерисовку, кадры будут отрисовываться один за другим максимально быстро, а не как в демо у автора, когда отмены рендерколлов, следующие один за другим непрерывно, суммируют задержки между кадрами вплоть до момента, когда юзер наконец сделает достаточно большую паузу, чтоб текущее состояние успело отрисоваться.
@igormalykhin55283 ай бұрын
Автору искренняя благодарность за ролики. На собесе благодаря Вашему ролику про react key отличился знанием. Пожалуйста, продолжайте в том же духе
@it-sin9k3 ай бұрын
хех) очень рад, что видео оказались полезными) не раз слышал, что люди по ним готовятся к собеседовниям) значит все не зря)
@ddflruc2 ай бұрын
Невероятно крутой контент и понятные визуализации! У вас талант! Спасибо огромное!!!
@it-sin9k2 ай бұрын
спасибо!
@eugenetit80723 ай бұрын
Шикарный выпуск!!! Помог аккуратно решить проблему)
@sergeymalakhov55782 ай бұрын
Отличная подача! Спасибо!
@deker92963 ай бұрын
Очень интересно и полезно, спасибо!
@archibaldstriebendrossel3 ай бұрын
Отличия от debounce: 1. Юзер увидит конечную картинку раньше, т.к. useDeferredValue начинает её рендерить сразу, а не после таймаута. 2. Не будет фризов в инпуте с какой бы скоростью юзер не печатал. С debounce юзер может попадать в просак между срабатыванием таймера и окончанием рендера. 3. Потенциально больше жрёт процессор.
@Chastor972 ай бұрын
классный ролик. Круто
@_GyG_3 ай бұрын
Спасибо Синяк! Как всегда круто и доступно объяснил!
@it-sin9k3 ай бұрын
Спасибо за слова поддержки!)
@Sameyl13 ай бұрын
Блин круто, спасибо,пушка бомба)
@ИгорьГолуб-н6щ3 ай бұрын
Супер! Спасибо за контент. Полезно!
@АлексейСоколов-у3к3 ай бұрын
супер ролик! Синяк как всегда на высоте!
@it-sin9k3 ай бұрын
спасибо! низкий поклон за приятный слова)
@boldureans3 ай бұрын
Привет Саш, спасибо за видео!
@aaliboyev3 ай бұрын
Очень полезная информация. Большинство разработчиков никогда не используют хуки кроме useState и useEffect.
@it-sin9k2 ай бұрын
видимо у них простые приложения)
@Ramosok3 ай бұрын
❤как всегда очень круто!
@dev_zloi3 ай бұрын
Получается основное преимущество, что зависит от мощности железа, а не от захардкоженной цифровой в setTimeot. Но как же все быть, если летит бесконечный поток данных в сокете?
@it-sin9k3 ай бұрын
как и с debounce это будет ждать момента, когда хоть на момент поток данных прервется
@Kotovar3 ай бұрын
Спасибо, было полезно)
@johnstark30453 ай бұрын
Отлично 🔥
@АлександрВолков-о8ю3 ай бұрын
Спасибо, теперь буду знать, что можно не костылить дебаунсом
@BahramJabbarov-m4u3 ай бұрын
Это очень круто!
@NeoCoding3 ай бұрын
спасибо дорогой
@ОлегСелин-ш9ы3 ай бұрын
Спасибо, любопытная штука.
@AlexanderBorshak3 ай бұрын
Шо, опять?.. ))) (За видео - лайк! Коммент скорее к разработчикам реакта.)
@AlexanderBorshak3 ай бұрын
И по сути вопроса. В чем наша проблема? Есть какая-то синхронная задача, которая тормозит рендер. Напрашивается логичное решение - сделать ее асинхронной; а если надо - то и обернуть внутри все в дебаунс или тротлинг, и затем уже изнутри асинхронной задачи обновлять стейт реакта, чтобы вызвать ререндер. Но создатели реакта почему-то не топятся показать всем идиоматичными примерами как надо делать в том или ином случае (включая наш), а спешат добавить новый костыль, который - как оказывается из данного видео - еще и ломает поведение уже знакомых API реакта. Браво, еще!..
@EgorMoscowNeverSleep3 ай бұрын
useDeferredValue полезен в связке с (будущим) хуком use, для реализации асинхронного состояния. Но, опять же, реализация на сигналах будет лучше.
@antonklochkov34163 ай бұрын
Спасибо, было интересно, но пример с графиками и не прерывным потоком данных для графика будто не очень хороший, так как если правильно понял, у нас пока летят данные отображаться графики не будут, а будут ждать когда поток либо закроется или хотя бы перестанет лететь без остановки. Если не прав подсветите, может что не так понял.
@it-sin9k2 ай бұрын
да, вы все верно поняли. Идея этого примера в том, что поток данных все же совсем бесконечным не бывает. Идея в том, что ваше устройство выждет этот момент короткой передышки вашего устройства и сразу же обновит интерфейс
@ОлегСелин-ш9ы3 ай бұрын
Посмотрел ещё раз внимательно, почитал замечания. Штука действительно интересная, но область её применения, мне, не понятна. Если поток событий запускает сложные, прерываемые вычисления и последующую отрисовку, так лучше использовать debounce или throttle. Так хотя бы не будет бесполезной нагрузки на процессор. Опять же мобилки батарею экономят.
@it-sin9k3 ай бұрын
если цель стоит снизить нагрузку на CPU, то однозначно этот хук не лучший выбор. Но если задача стоит например выжать из вашего девайса максимум, для крутого экспириенса, то тут он пригодится)
@alexeyshaykov3 ай бұрын
с ума сойти! спасибо
@ГенаФес-ъ9з3 ай бұрын
благодарю!
@vladhanov15303 ай бұрын
А так то это намного лучше дебаунса в смысле лагов интерфейса. Об этом в видео не совсем чётко сказано. Дебаунс будет ждать от последнего нажатия. А тут все это время будет использовано для драфт (пока ещё) три. Гениально.
@it-sin9k2 ай бұрын
защита от лагов состоит в том, что тяжелые пересчеты можно откладывать, точно так же как и с debounce. Только разница как я и говорил с debounce в том, что оно полагается на мощность твоего компьютера, а не на константу времени
@egorovsa3 ай бұрын
Пасип, некогда даже новые фичи посмотреть, не то что их попробовать и уж тем более сразу пускать в прод. Однако какие бы и сколь сложные интерфейсы я не делал, всегда тем не менее обходился дебаунсером. Но смысл я уловил. Дебаунсер ты хардкодиш тайминги, а тут энжин сам смотрит может ли он схавать поток или нет. Однако...
@duoduoo67323 ай бұрын
как узнается что это последний рендер
@it-sin9k3 ай бұрын
он не узнает последний рендер или не последний. Тут логика такая, useDeferredValue пытается закончить draft рендер, если ему хватило времени его закончить и вмонтировать в реальный DOM, тогда это и есть последний успешный, если не успел, он попробует еще раз
@duoduoo67323 ай бұрын
@@it-sin9k спасибо я вас люблю. простите я плохо знаю русский
@EgorMoscowNeverSleep3 ай бұрын
useDeferredValue хуже чем любая реализация сигналов. Нафиг он нужен, не очень понятно. По капотом этот хук использует Promise.reject, чтобы сигнализировать об асинхронном процессе + лишний рендер для каждого изменения. При использовании сигналов, будет только один рендер. Update: Написал комментарий не посмотрев видео, думал будет речь про связку useDeferredValue + use, а тут про SlowList. Безусловно, для SlowList useDeferredValue полезен.
@it-sin9k3 ай бұрын
о каких именно сигналах в рамках React идет речь?
@Илья-с1л6э3 ай бұрын
почему при использовании сигналов будет только один рендер? Будет так же рендер на каждое изменение инпута. Но рендер будет более атомарным
@EgorMoscowNeverSleep3 ай бұрын
@@it-sin9k я для себя сделал собственную реализацию. А так, погуглите. Любая реализация сигналов у которой есть хук useSignal подойдёт.
@EgorMoscowNeverSleep3 ай бұрын
Update: Написал комментарий не посмотрев видео, думал будет речь про связку useDeferredValue + use, а тут про SlowList. Безусловно, для SlowList useDeferredValue полезен.
@popuguytheparrot_3 ай бұрын
Точно предыдущий результат "выбрасывается на помойку"? Планировщик реакта как раз имеет механизм переиспользовать предыдущую работу
@levsonc3 ай бұрын
Данные поменялись - следовательно, поменялся рендер.
@popuguytheparrot_2 ай бұрын
@@levsonc и? Рендер ещё не произошел
@Chuv1113 ай бұрын
Как то сомнительно выглядит. Все время такие проблемы решались с debounce. А что теперь? Нагружаем процессор бесполезными вычислениями и тратим заряд батареи на устройствах только ради того, что бы чуть более точно подобрать задержку debounce
@Lear-fe6se3 ай бұрын
Вообще фича полезная для отображения данных, приходящих с сервера. Если рендер в основном задерживают асинхронные запросы, то там высокой нагрузки не будет. Но вот с такими кейсами, как тяжёлые вычисления на фронте, она действительно может привести к лишней трате заряда
@it-sin9k3 ай бұрын
если вы хотите использовать debounce это же не проблема) выбирайте инструмент, который вам нравится :)
@Chuv1113 ай бұрын
@@Lear-fe6se А что принципиально поменяется если с сервера будут данные приходить, а не из инпута? С сервером по идее вообще проблем не должно быть, вряд ли вы будете присылать обновления с сервера с настолько высокой частотой, что интерфейс не будет успевать рендериться.
@Lear-fe6se3 ай бұрын
@@Chuv111 нет, я другую ситуацию представляю: Данные получаем из инпута, но рендер у нас медленный не потому, что нужно отрисовать таблицу с миллионом строк, а потому что нужно отправить запрос на сервер и дождаться ответа. В таком случае useDefferedValue не нагрузит клиентское устройство, но отзывчивость повысится в сравнении с debounce. Да, нагрузка на сервер может увеличиться. Но это не так критично, как для клиента. Плюс отправленные запросы можно отменять
@Chuv1113 ай бұрын
@@it-sin9k Я пытаюсь понять в каких случаях useDeferredValue будет лучшим выбором. Так то фича выглядит интересно, но пример в видео выбран не очень удачно. Единственный плюс, который мне приходит в голову, это то что не надо свой хук для debounce писать и придумывать значение задержки. Про минусы я уже написал
@МаксимСинькевич-в2я3 ай бұрын
1ый😎
@tagnati55853 ай бұрын
Мля, я второй
@ParaZumir22 күн бұрын
Bomba🎉
@kaifaty3 ай бұрын
По итогу весь maintread забит реактовскими бесполезными вычислениями с 0 результатом. Ммм, вкуснятина
@corvus2783 ай бұрын
Так они и до этого были бесполезными, только из ещё больше было
@Chuv1113 ай бұрын
@@corvus278 До этого юзали debounce с фиксированой задержкой, и никаких лишних вычислений не было
@kaifaty3 ай бұрын
@@corvus278 там в промежутке хоть что-то выводилось в процессе ввода