⚡ Reduce commit cost when dropping large selections (#12032)

Collect children ids into one transient vector and track WASM shape
changes in a JS Map instead of a volatile persistent map.

AI-assisted-by: claude-opus-5-5
This commit is contained in:
Elena Torró 2026-10-02 11:22:19 +02:00 committed by GitHub
parent 3a0ed93360
commit 13a9da3bc3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 19 additions and 14 deletions

View File

@ -162,14 +162,15 @@
([objects id {:keys [ignore-children-fn]
;;ignore-children-fn should receive a shape and return a boolean
:or {ignore-children-fn (constantly false)}}]
(letfn [(get-children-ids-rec [id processed]
(when-not (contains? processed id)
(when-let [shapes (as-> (get objects id) $
(:shapes $)
(remove ignore-children-fn $)
(some-> $ vec))]
(into shapes (mapcat #(get-children-ids-rec % (conj processed id))) shapes))))]
(get-children-ids-rec id #{}))))
(letfn [(collect [result id processed]
(if (contains? processed id)
result
(let [shapes (into [] (remove ignore-children-fn) (dm/get-in objects [id :shapes]))
processed (conj processed id)]
(reduce #(collect %1 %2 processed)
(reduce conj! result shapes)
shapes))))]
(persistent! (collect (transient []) id #{})))))
(defn get-children-ids-with-self
[objects id]

View File

@ -133,14 +133,14 @@
(if (and (not ignore-wasm?) (features/active-feature? state "render-wasm/v1"))
;; Update the wasm model
(let [shape-changes (volatile! {})
(let [shape-changes (js/Map.)
state
(binding [cts/*shape-changes* shape-changes]
(update-in state [:files file-id :data] apply-changes))]
(let [objects (dm/get-in state [:files file-id :data :pages-index (:current-page-id state) :objects])]
(wasm.shape/process-shape-changes! objects @shape-changes))
(wasm.shape/process-shape-changes! objects (es6-iterator-seq (.entries shape-changes))))
state)

View File

@ -348,10 +348,15 @@
;; `conj` empty set initialization
(def conj* (fnil conj (d/ordered-set)))
(defn- track-change!
[self k]
(when-let [changes shape/*shape-changes*]
(let [id (:id self)]
(.set changes id (conj* (.get changes id) k)))))
(defn- impl-assoc
[self k v]
(when shape/*shape-changes*
(vswap! shape/*shape-changes* update (:id self) conj* k))
(track-change! self k)
(case k
:id
@ -379,8 +384,7 @@
(defn- impl-dissoc
[self k]
(when shape/*shape-changes*
(vswap! shape/*shape-changes* update (:id self) conj* k))
(track-change! self k)
(case k
:id