Как постоянные структуры данных помогают сделать 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 старого и нового состояния является точно таким же объектом и, следовательно, не может иметь никаких изменений в любом вложенном состоянии, потому что оно неизменное.

Другие вопросы по тегам