Comments 9
Ууууууф, честно говоря, сложновато. Предложил бы сначала "на кубиках" объяснить общие понятия и концепции работы, а уже потом погружать в поля, классы, код. А то сейчас не очень складывается понимание, что там происходит
Как выглядит и работает очередь задач? Как расставляются приоритеты? Это как рассказывать eventlooop описывая только сигнатуры всяких requestAnimationFrame
А как практически можно применить эти знания ?
В первую очередь, на практике, без хотя бы общего понимания внутренних процессов React, почти невозможно пользоваться, например, штатным React-профилировщиком, с целью дебага производительности, утечек памяти и т.д.
А вообще, статья задумывалась, как отправная точка в серии статей о реакте, где я планирую рассмотреть отдельные процессы более подробно.
без хотя бы общего понимания внутренних процессов React
Общее понимание есть у всех, кто пользуется реактом.
У вас в статье описываются внутренности.
Мне все равно кажется - это нужно на столько же, на сколько надо понимать все процессы, которые происходят в ядре линукса или windows, что бы его устанавливать на компьютере. То есть простому пользователю совсем не нужно. А если это в реакте уже необходимость, то стоит подумать, надо ли его вообще использовать.
> пользоваться, например, штатным React-профилировщиком
Вот это было бы интересно почитать. Но для этого опять же знать внутренности досканально нет смысла.
Ваше сравнение с "Линуксом и установкой" нерелевантно. Как ламер и нуб вы конечно можете считать себя правым.
Но вот из таких мнений и получается что есть куча недодевелоперов под реакт. Которые умеют печатать что-то, а по факту все что они создают - спагетти. у которого большие проблемы с производительностью.
Очень много разработчиков под реакт, пренебрегают изучением документации, а она почти на каждом углу рассказывает про react component lifecycle и reconciliation. И не только это, этиже девелоперы банально не знают суть "shallow сравнений" в react.
Общее понимание есть у всех, кто пользуется реактом.
То что я вижу на рынке рекрутинга, то что очень много людей как мартышки, выучили что и как печатать, а объяснить почему так - не могут.
Автор и так максимально обзорно попытался описать всего лишь 1 процесс! И там есть еще многое о чем можно рассказать.
Автор полностью прав:
без хотя бы общего понимания внутренних процессов React, почти невозможно пользоваться, например, штатным React-профилировщиком, с целью дебага производительности, утечек памяти
Большое спасибо автору за труд и статью. С нетерпением жду продолжения.
И как сказал автор из предыдущего комментария:
...пользоваться, например, штатным React-профилировщиком...
Вот это было бы интересно почитать.
Происходит это так же, в отдельной микротаске, в которой происходит ряд проверок, в том числе, определяется и приоритет следующей задачи.
Не совсем понятно, а как определяется приоритет следующей задачи?
Планировщик занимается обработкой поставленных в очередь задач (Fiber-ов) и всегда работает в микротаске или после завершение обработки текущего события. Конкретный рендер имеет возможность определить свою специфику работы планировщика посредством переопределения
scheduleMicrotask
в API пакетаreact-reconciler
. НапримерReact Native
может использовать для этих целейqueueMicrotask
, если поддерживается платформой, аReact DOM
- промисы.
Вот это тоже любопытно, как конкретный рендер определяют свою специфику планировщика, от чего это зависит? где можно читать об этом?
А так - спасибо большое за статью, невероятно круто!
Было бы здорово, если бы вы нарисовали простой скетч механизма (например, в excalidraw), а то иногда может быть сложно слету понять ход мыслей, когда нет какой-то схемы
В первую очередь, хочу поблагодарить за подробный разбор. Честно говоря, неоднократно приходилось перечитывать, так как терялись нить рассуждений и по прежнему в голове не складывается общая картина.
Однако, вспоминая различная статьи о том, как работает реакт. Хотел понять, где же здесь реализован эвристический алгоритм?=)
Если резюмировать кратко и очень грубо, то выходит есть пакеты, которые формируют определенную структуру, затем это структура обрабатывается и обновляется. Если возможность поверхносто расписать, чтобы при прочтении это можно было удерживать в голове и более детальные кейсы на это накидывать. Буду очень признателен
А что вы подразумеваете под эвристическим алгоритмом? Знаменитую фразу, что полное сравнение деревьев при реконсилиации занимает O(n^3), а мы сделали так, что работает за O(n) ? Или общие оптимизационные техники, которые применяются в кодовой базе реакта?
Если вы про первое, то в общих чертах их эвристика достаточна прямолинейна. Это сравнение сначала по key
. Если они не совпадают, дальнейшие проверки \ сравнения не производятся, а полностью пересоздается файбер. Потом идет сравнение по type
. Потом сравнение props
через shallowEqual... Благодаря чему объем сравнений сокращается в разы.
Если про второе, то там много хитрых наворотов. Это серьезная работа на уровне ссылочных структур данных (деревья файберов, списки обновлений). Это и применение битовых масок для выражения различных идей (фазы рендеринга, приоритета обновления, результата построения WIP файбер дерева и тд). Это и правильный подбор структур данных под необходимые им нужды, как например min heap для сортировки списка задач. И подбор оптимальных средств API host среды, где выполняется react, типа PostMessage или isInputPending. Копать не перекопать.
Детальный React. Реконсиляция, рендеры, Fiber, виртуальное дерево