новичкам трудно понять зачем нужен useDeferredValue если можно написать debounce. Разница в том, useDeferredValue будет задерживать значения в зависимости от возможностей железа пользователя. На быстром будет срабатывать быстро а на слабом медленнее подстраиваясь под рендер каждого девайса. Т.е не нужен хардкод таймаута.
@it-sin9kАй бұрын
Хорошо сказано!)
@AA-VezelАй бұрын
С другой стороны, uDV будет нагружать машину пользователя, тратить киловатты (эффект масштаба) на пустые обсчеты и тем самым увеличивая углеродный след. Как бы нам зелёные звиздюлей не дали за такую оптимизацию 😂
@Sameyl1Ай бұрын
Ну это и было сказано в видосе) прикольная тема конечно
@CJIu3eHbАй бұрын
@@AA-Vezel "Машины должны страдать", и зеленые тоже... :)
@paveludaloff7294Ай бұрын
Там idle callback под капотом?
@gtsjdmАй бұрын
У меня на проекте была задача при изменении зума карты, отображать в боковом меню список точек которые попадают в зону видимости карты. Так вот этот хук идеально вписался в решение этой задачи, помогая пропускать промежуточные ненужные рендеры, например пока пользователь быстро колесом мыши зумит туда сюда)
@it-sin9kАй бұрын
очень крутой кейс!) спасибо что поделились!) интересно только как вы работали с запросами в левом меню, вы их тоже отправляли и отменяли с помощью abort controller при быстром скроле? я име ввиду для draft рендеров
@gtsjdmАй бұрын
@@it-sin9k там все было проще, один запрос на все точки при инициализации, точек не так много чуть больше 300. Лаг был именно в сайдбаре, при частых пересчетах самого списка.
@it-sin9kАй бұрын
прикольно) спасибо за ответ)
@bislan-aranyanАй бұрын
спасибо за выпуск, очень интересно было послушать, как можно использовать useDeferredValue и что твориться под копотом
@igormalykhin5528Ай бұрын
Автору искренняя благодарность за ролики. На собесе благодаря Вашему ролику про react key отличился знанием. Пожалуйста, продолжайте в том же духе
@it-sin9kАй бұрын
хех) очень рад, что видео оказались полезными) не раз слышал, что люди по ним готовятся к собеседовниям) значит все не зря)
@archibaldstriebendrosselАй бұрын
Отличия от debounce: 1. Юзер увидит конечную картинку раньше, т.к. useDeferredValue начинает её рендерить сразу, а не после таймаута. 2. Не будет фризов в инпуте с какой бы скоростью юзер не печатал. С debounce юзер может попадать в просак между срабатыванием таймера и окончанием рендера. 3. Потенциально больше жрёт процессор.
@The14Some1Ай бұрын
Автор, ты так и не сделал одно очень важное замечание: Поскольку реакт отбрасывает те рендеры, которые он не успевает, если новые изменения происходят до окончания рендера, то мы увидим следующий рендер только когда поток изменений будет содержать достаточно большую паузу, чтоб ререндер успел успешно завершиться. Эта особенность делает данный подход неприемлемым как раз в тех случаях, о которых ты упомянул, а именно на 3:33. Если поток данных будет продолжаться непрерывно, то может возникнуть ситуация, что на рендер не будет хватать времени вообще никогда. И пользователь вообще не будет видеть обновлений. Правильным решением было бы делать ререндеры по мере их фактической возможности один за другим и не отменять рендеры при появлении новых изменений. При этом данные под каждый рендер-колл брать на момент получения заявки на этот рендер-колл. Как было: каждое изменение порождало свой рендер-колл, и блочило движок до окончания ререндера Как сейчас: каждое изменение порождает новый рендер-колл асинхронно, и если ререндер уже производится, то отменяет устаревший ререндер Как нужно: каждое изменение инвалидирует состояние, что является триггером для создания нового рендер-колла рендер-коллы выполняются в отдельном потоке один за другим, не блоча движок, и нет механизма отмены старого "устаревшего" рендер-колла.
@it-sin9kАй бұрын
Они как то рассказывали, что тестировали варианты использования соседних потоков для разгружения основного, но насколько я помню, это слишком медленно работало и отказались
@archibaldstriebendrosselАй бұрын
Когда не хватает мощности для отрисовки, у нас есть выбор: рисовать все кадры, но тормозить, или пропускать кадры, но быстро. Debounce и useDeferredValue - про второе. Ваше решение - про первое. Мощности ваше решение не добавляет, т.к. не распараллеливает нагрузку, а выносит её в другой поток. Что, вообще-то, непонятно как сделать. Почему? Это проще понять на практике, чем описать в комментарии. Дальше, если мы не можем вынести значительную часть нагрузки в отдельный поток, значит не можем и распараллелить. Даже если существует способ это сделать, он скорей всего предполагает ухудшение DX и увеличение общей нагрузки на компьютер в обмен на увеличение throughput и незначительное уменьшение latency. А именно latency нас и волнует. С таким раскладом можно потратить много сил и времени на проработку, и получить около бесполезную технологию.
@The14Some1Ай бұрын
@@archibaldstriebendrossel я не предлагал рисовать все кадры, но тормозить. Я предлагал не отменять устаревшие недорисованные кадры, а дорисовывать, и как только кадр отрисован, брать текущее состояние, и начинать рисовать снова. Пока есть заявки на перерисовку, кадры будут отрисовываться один за другим максимально быстро, а не как в демо у автора, когда отмены рендерколлов, следующие один за другим непрерывно, суммируют задержки между кадрами вплоть до момента, когда юзер наконец сделает достаточно большую паузу, чтоб текущее состояние успело отрисоваться.
@ddflruc27 күн бұрын
Невероятно крутой контент и понятные визуализации! У вас талант! Спасибо огромное!!!
@it-sin9k23 күн бұрын
спасибо!
@sergeymalakhov5578Ай бұрын
Отличная подача! Спасибо!
@eugenetit8072Ай бұрын
Шикарный выпуск!!! Помог аккуратно решить проблему)
@deker9296Ай бұрын
Очень интересно и полезно, спасибо!
@АлександрВолков-о8юАй бұрын
Спасибо, теперь буду знать, что можно не костылить дебаунсом
@aaliboyevАй бұрын
Очень полезная информация. Большинство разработчиков никогда не используют хуки кроме useState и useEffect.
@it-sin9kАй бұрын
видимо у них простые приложения)
@_GyG_Ай бұрын
Спасибо Синяк! Как всегда круто и доступно объяснил!
@it-sin9kАй бұрын
Спасибо за слова поддержки!)
@Chastor9722 күн бұрын
классный ролик. Круто
@ИгорьГолуб-н6щАй бұрын
Супер! Спасибо за контент. Полезно!
@boldureansАй бұрын
Привет Саш, спасибо за видео!
@dev_zloiАй бұрын
Получается основное преимущество, что зависит от мощности железа, а не от захардкоженной цифровой в setTimeot. Но как же все быть, если летит бесконечный поток данных в сокете?
@it-sin9kАй бұрын
как и с debounce это будет ждать момента, когда хоть на момент поток данных прервется
@AlexanderBorshakАй бұрын
Шо, опять?.. ))) (За видео - лайк! Коммент скорее к разработчикам реакта.)
@AlexanderBorshakАй бұрын
И по сути вопроса. В чем наша проблема? Есть какая-то синхронная задача, которая тормозит рендер. Напрашивается логичное решение - сделать ее асинхронной; а если надо - то и обернуть внутри все в дебаунс или тротлинг, и затем уже изнутри асинхронной задачи обновлять стейт реакта, чтобы вызвать ререндер. Но создатели реакта почему-то не топятся показать всем идиоматичными примерами как надо делать в том или ином случае (включая наш), а спешат добавить новый костыль, который - как оказывается из данного видео - еще и ломает поведение уже знакомых API реакта. Браво, еще!..
@АлексейСоколов-у3кАй бұрын
супер ролик! Синяк как всегда на высоте!
@it-sin9kАй бұрын
спасибо! низкий поклон за приятный слова)
@Sameyl1Ай бұрын
Блин круто, спасибо,пушка бомба)
@KotovarАй бұрын
Спасибо, было полезно)
@RamosokАй бұрын
❤как всегда очень круто!
@EgorMoscowNeverSleepАй бұрын
useDeferredValue полезен в связке с (будущим) хуком use, для реализации асинхронного состояния. Но, опять же, реализация на сигналах будет лучше.
@vladhanov1530Ай бұрын
А так то это намного лучше дебаунса в смысле лагов интерфейса. Об этом в видео не совсем чётко сказано. Дебаунс будет ждать от последнего нажатия. А тут все это время будет использовано для драфт (пока ещё) три. Гениально.
@it-sin9kАй бұрын
защита от лагов состоит в том, что тяжелые пересчеты можно откладывать, точно так же как и с debounce. Только разница как я и говорил с debounce в том, что оно полагается на мощность твоего компьютера, а не на константу времени
@ОлегСелин-ш9ыАй бұрын
Посмотрел ещё раз внимательно, почитал замечания. Штука действительно интересная, но область её применения, мне, не понятна. Если поток событий запускает сложные, прерываемые вычисления и последующую отрисовку, так лучше использовать debounce или throttle. Так хотя бы не будет бесполезной нагрузки на процессор. Опять же мобилки батарею экономят.
@it-sin9kАй бұрын
если цель стоит снизить нагрузку на CPU, то однозначно этот хук не лучший выбор. Но если задача стоит например выжать из вашего девайса максимум, для крутого экспириенса, то тут он пригодится)
@NeoCodingАй бұрын
спасибо дорогой
@ОлегСелин-ш9ыАй бұрын
Спасибо, любопытная штука.
@johnstark3045Ай бұрын
Отлично 🔥
@ГенаФес-ъ9зАй бұрын
благодарю!
@BahramJabbarov-m4uАй бұрын
Это очень круто!
@alexeyshaykovАй бұрын
с ума сойти! спасибо
@antonklochkov3416Ай бұрын
Спасибо, было интересно, но пример с графиками и не прерывным потоком данных для графика будто не очень хороший, так как если правильно понял, у нас пока летят данные отображаться графики не будут, а будут ждать когда поток либо закроется или хотя бы перестанет лететь без остановки. Если не прав подсветите, может что не так понял.
@it-sin9kАй бұрын
да, вы все верно поняли. Идея этого примера в том, что поток данных все же совсем бесконечным не бывает. Идея в том, что ваше устройство выждет этот момент короткой передышки вашего устройства и сразу же обновит интерфейс
@egorovsaАй бұрын
Пасип, некогда даже новые фичи посмотреть, не то что их попробовать и уж тем более сразу пускать в прод. Однако какие бы и сколь сложные интерфейсы я не делал, всегда тем не менее обходился дебаунсером. Но смысл я уловил. Дебаунсер ты хардкодиш тайминги, а тут энжин сам смотрит может ли он схавать поток или нет. Однако...
@EgorMoscowNeverSleepАй бұрын
useDeferredValue хуже чем любая реализация сигналов. Нафиг он нужен, не очень понятно. По капотом этот хук использует Promise.reject, чтобы сигнализировать об асинхронном процессе + лишний рендер для каждого изменения. При использовании сигналов, будет только один рендер. Update: Написал комментарий не посмотрев видео, думал будет речь про связку useDeferredValue + use, а тут про SlowList. Безусловно, для SlowList useDeferredValue полезен.
@it-sin9kАй бұрын
о каких именно сигналах в рамках React идет речь?
@Илья-с1л6эАй бұрын
почему при использовании сигналов будет только один рендер? Будет так же рендер на каждое изменение инпута. Но рендер будет более атомарным
@EgorMoscowNeverSleepАй бұрын
@@it-sin9k я для себя сделал собственную реализацию. А так, погуглите. Любая реализация сигналов у которой есть хук useSignal подойдёт.
@EgorMoscowNeverSleepАй бұрын
Update: Написал комментарий не посмотрев видео, думал будет речь про связку useDeferredValue + use, а тут про SlowList. Безусловно, для SlowList useDeferredValue полезен.
@duoduoo6732Ай бұрын
как узнается что это последний рендер
@it-sin9kАй бұрын
он не узнает последний рендер или не последний. Тут логика такая, useDeferredValue пытается закончить draft рендер, если ему хватило времени его закончить и вмонтировать в реальный DOM, тогда это и есть последний успешный, если не успел, он попробует еще раз
@duoduoo6732Ай бұрын
@@it-sin9k спасибо я вас люблю. простите я плохо знаю русский
@popuguytheparrot_Ай бұрын
Точно предыдущий результат "выбрасывается на помойку"? Планировщик реакта как раз имеет механизм переиспользовать предыдущую работу
@levsoncАй бұрын
Данные поменялись - следовательно, поменялся рендер.
@popuguytheparrot_Ай бұрын
@@levsonc и? Рендер ещё не произошел
@Chuv111Ай бұрын
Как то сомнительно выглядит. Все время такие проблемы решались с debounce. А что теперь? Нагружаем процессор бесполезными вычислениями и тратим заряд батареи на устройствах только ради того, что бы чуть более точно подобрать задержку debounce
@Lear-fe6seАй бұрын
Вообще фича полезная для отображения данных, приходящих с сервера. Если рендер в основном задерживают асинхронные запросы, то там высокой нагрузки не будет. Но вот с такими кейсами, как тяжёлые вычисления на фронте, она действительно может привести к лишней трате заряда
@it-sin9kАй бұрын
если вы хотите использовать debounce это же не проблема) выбирайте инструмент, который вам нравится :)
@Chuv111Ай бұрын
@@Lear-fe6se А что принципиально поменяется если с сервера будут данные приходить, а не из инпута? С сервером по идее вообще проблем не должно быть, вряд ли вы будете присылать обновления с сервера с настолько высокой частотой, что интерфейс не будет успевать рендериться.
@Lear-fe6seАй бұрын
@@Chuv111 нет, я другую ситуацию представляю: Данные получаем из инпута, но рендер у нас медленный не потому, что нужно отрисовать таблицу с миллионом строк, а потому что нужно отправить запрос на сервер и дождаться ответа. В таком случае useDefferedValue не нагрузит клиентское устройство, но отзывчивость повысится в сравнении с debounce. Да, нагрузка на сервер может увеличиться. Но это не так критично, как для клиента. Плюс отправленные запросы можно отменять
@Chuv111Ай бұрын
@@it-sin9k Я пытаюсь понять в каких случаях useDeferredValue будет лучшим выбором. Так то фича выглядит интересно, но пример в видео выбран не очень удачно. Единственный плюс, который мне приходит в голову, это то что не надо свой хук для debounce писать и придумывать значение задержки. Про минусы я уже написал
@МаксимСинькевич-в2яАй бұрын
1ый😎
@tagnati5585Ай бұрын
Мля, я второй
@kaifatyАй бұрын
По итогу весь maintread забит реактовскими бесполезными вычислениями с 0 результатом. Ммм, вкуснятина
@corvus278Ай бұрын
Так они и до этого были бесполезными, только из ещё больше было
@Chuv111Ай бұрын
@@corvus278 До этого юзали debounce с фиксированой задержкой, и никаких лишних вычислений не было
@kaifatyАй бұрын
@@corvus278 там в промежутке хоть что-то выводилось в процессе ввода