Как постоянные структуры данных помогают сделать Om быстрее
Говорят, что Om, оболочка Clojurescript React, очень быстрая, потому что она использует неизменность. Я не могу понять, как постоянные структуры данных могут помочь здесь.
Я понял, что состояние приложения - это атом. Это состояние передается функциям (ом-компонентам), которые возвращают виртуальные узлы DOM, так что создание "исправления" различий между текущим виртуальным DOM и его предыдущим состоянием намного лучше, чем работа непосредственно с фактическим DOM.
Но где здесь могут помочь постоянные структуры данных?
(def app-state (atom {:foo {:counter 0}))
(om/root click-counter app-state {:target ...})
например click-counter
сделать кнопку, которая при нажатии увеличивает счетчик. Итак, функция перехода выглядит так:
(dom/button #js {:onClick #(om/transact! app [:foo :counter] inc)}
(str "clicked " (-> app :foo :counter) " times"))
Я понимаю это: когда onClick
выполняется clojurescript создает новую карту (очень эффективно), как это:
{:foo {:counter 1}}
а также app-state
теперь указывает на новую карту. На данный момент Om знает, что состояние изменяется, потому что это всего лишь одна проверка на равенство.
Проблема здесь в том, что Om все равно должен вычислять разницу между всем старым виртуальным DOM и новым. Он не знает, что просто счетчик изменился.
Где моя ошибка?
1 ответ
Когда состояние приложения хранится в постоянной древовидной структуре, такой как карта, сразу становится ясно, какие части дерева состояний не изменились и не нуждаются в обновлении. Это потому, что любое изменение дочернего элемента меняет родителя. С изменчивыми структурами данных изменения для детей не должны менять родителей.
Так что, если ваше состояние выглядело так:
{:part1 [1 2 3 4]
:part2 [:a :b]}
и вы создаете новое состояние, добавляя что-то в part2:
{:part1 [1 2 3 4]
:part2 [:a :b :c]}
тогда функция сравнения может посмотреть и увидеть, что значение в:part1 старого и нового состояния является точно таким же объектом и, следовательно, не может иметь никаких изменений в любом вложенном состоянии, потому что оно неизменное.