Fork me on GitHub
#clojure-norway
<
2023-12-26
>
slipset10:12:41

God jul og greier! Nå skal jeg gjøre en @leif.eric.fredheim:

(defn hiccup->dom [old h]
  (if (= old h)
    old
    (if (string? h)
      (.createTextNode js/document h)
      (let [t (first h)
            v (rest h)
            old-v (rest old)
            e (.createElement js/document (name t))
            children (map (fn [x old-x-idx]
                            (let [h (hiccup->dom (get old-v old-x-idx) x)]
                              (if-let [child (:e (meta h))]
                                child
                                h))) v (range (count v)))]
        (doseq [c children]
          (.appendChild e c))
        (with-meta h {:e e})))))

(def old-hickup (atom nil))

(defn render [root hiccup]
  (let [new-hickup (hiccup->dom @old-hickup hiccup)]
    (.replaceChildren root (:e (meta new-hickup)))
    (reset! old-hickup new-hickup)))
Dette er “maten” i mitt cljs-react thingy. Det håndterer ennå ikke et map som andre parameter i hiccup’en, men det ser ut som om det ikke rerendrer så altfor mye. Det er veldig skummelt å legge ut noe slikt, fordi det er sånn kode som jeg synes er litt vanskelig å skrive.

slipset10:12:53

Litt veldig irr at man ikke kan ha meta på en string i clj(s), fordi hele tilnærmingen min baserer seg på å legge den genererte domnoden som meta på hickup’en.

slipset10:12:59

Videre er tanken at en “komponent” i denne greia her er bare en memoized funksjon.

❤️ 1
slipset10:12:12

(defn sayit [s]
  [:span (str "Hello " s)])

(def Sayit (memoize sayit))

slipset11:12:49

Jeg håper virkelig at dette er for naivt på en eller annen måte. Det er jo for kjipt hvis man kan implementere react i under 100 linjer (det er jo noe funksjonalitet som gjennstår) cljs.

cjohansen13:12:39

Det er litt mer til det for å få god nok ytelse 😅

cjohansen13:12:32

Jeg tror hovedproblemet med denne tilnærmingen er at du alltid må rerendre fra toppen ned til noden som endrer seg. Jeg tok et tilsvarende utgangspunkt, men inkluderer ikke barna i lilhetssjekken, og har logikk for å hoppe over barna som er like, flytte noder som har flytta seg osv. Selv med en del sånne optimaliseringer kom mitt første forsøk nokså dårlig ut i en benchmark. Skal se litt mer på det ved anledning.

slipset17:12:33

Men må du ikke alltid det, sånn generelt?

slipset17:12:54

(eller kanskje det bare må layoutes?)

cjohansen17:12:40

Mange endringer kan skje helt lokalt. Og jeg tror en full rebuild er dyrere enn ny layout.