React и DOM дерево
Всякий раз, когда я сталкиваюсь с проблемами в работе с React, это происходит потому, что я не очень хорошо понимаю, как он работает на самом деле.
Чтобы понять, как работает React, нам нужно понять проблему, для решения которой он был разработан.
Представьте, что сейчас 2013 год, и вы хотите заставить баннер появляться, когда пользователь нажимает на кнопку, просто используя JS.
Для этого нужно сделать три вещи:
- Отследить событие нажатия на кнопке
- Найти место в DOM, куда вы хотите добавить баннер
- Создать баннер и обновить DOM в этот момент
И тут есть одна проблема - каждый раз, когда вы обновляете DOM, это вызывает обновление пользовательского интерфейса, поскольку браузер рисует новую структуру дерева.
Эти обновления происходят медленно, поэтому их нужно свести к минимуму.
Но в приложении с большим количеством интерактивности у вас нет контроля над тем, когда и как часто происходят эти перетоки.
Два потока событий могут произойти один за другим и на мгновение заблокировать пользовательский интерфейс из-за перерисовок.
У React есть классное решение из коробки: он хранит копию DOM в памяти браузера.
Это называется виртуальным DOM и является основой того, что делает React (относительно) быстрым.
Любые изменения в вашем приложении перехватываются React и сначала применяются к этому виртуальному DOM.
🤖 Эти изменения происходят быстро, потому что они происходят виртуально и не вызывают никаких изменений пользовательского интерфейса.
Затем React сравнивает новую версию DOM с текущей версией (все еще находящейся в памяти).
Этот процесс называется diffing, и он использует целую кучу хитроумных приемов, чтобы определить, что именно изменилось.
Каждая часть дерева, в которой произошли изменения, помечается как загрязненная, и, как правило, все ее дочерние части тоже.
Затем все эти изменения собираются вместе и применяются одновременно.
Прелесть здесь в том, что делаются только необходимые обновления DOM.
Но это не волшебство.
Один из подводных камней заключается в том, что вы можете иногда делать вещи, которые непреднамеренно помечают компоненты как грязные, что приводит к ненужному повторному перерисовыванию целых частей дерева.
Это может показаться не очень важным в случае не особо больших компонентов, но помните, что этот процесс создания виртуального DOM повторно выполняет перерисовку всех ваших компонент.
Вызовы функций, объявления переменных, циклы по массивам и т.д. - все это выполняется заново! Это падение производительности со временем превращается в "смерть от тысячи порезов бумаги".
Именно поэтому в React есть такие инструменты, как memo, useMemo, useCallback
- они предоставляют React больше информации о том, следует ли обновлять определенный компонент или нет. Немного подробнее об этом писала тут.
На этом сегодня все, надеюсь вам это было полезно!
🤖 Чтобы не пропустить новые уроки подпишись на телеграм канал!