Repository: penpot/penpot
File: frontend/src/app/main/data/event.cljs (ClojureScript)

Code before:
  (if (and (exists? js/globalThis)
           (exists? (.-PerformanceObserver js/globalThis)))
    (rx/create
     (fn [subs]
       (let [observer
             (js/PerformanceObserver.
              (fn [list]
                (doseq [entry (.getEntries list)]
                  (when (and (= "longtask" (.-entryType entry))
                             (> (.-duration entry) min-longtask-time))
                    (rx/push! subs
                              {::event :observer-longtask
                               :duration (.-duration entry)})))))]
         (.observe observer #js {:entryTypes #js ["longtask"]})
         (fn []
           (.disconnect observer)))))
    (rx/empty)))

(defn store-performace-info
  []
  (letfn [(micro-benchmark [state]
            (let [start (js/performance.now)]
              (doseq [i (range 0 1e6)]
                (* (math/sin i) (math/sqrt i)))
              (let [end (js/performance.now)]
                (assoc-in state [:performance-info :bench-result] (- end start)))))

          (count-shapes [file]
            (if file
              (->> file :data :pages-index vals
                   (map (comp count :objects))
                   (reduce +))
              0))

          (count-library-data [files {:keys [id]}]
            (let [data (get-in files [id :data])]
              {:components (count (:components data))
               :colors (count (:colors data))
               :typographies (count (:typographies data))}))

          (save-file-data []
            (ptk/reify ::store-performance-info-save-file-data
              ptk/UpdateEvent
              (update [_ state]
                (let [file-id (get state :current-file-id)
                      file (get-in state [:files file-id])
                      file-size (count-shapes file)

                      libraries
                      (-> (refs/select-libraries (:files state) (:id file))
                          (update-vals (partial count-library-data (:files state))))

Review comment (performance):
I suggest replace the usage of assoc-in that requires building a vector for traveral to something like this

```clojure
(update state :performance-info assoc :bench-result (- end start))
```

Code after:
         (fn []
           (.disconnect observer)))))
    (rx/empty)))

(defn performance-observer-longtask-stream
  []
  (if (and (exists? js/globalThis)
           (exists? (.-PerformanceObserver js/globalThis)))
    (rx/create
     (fn [subs]
       (let [observer
             (js/PerformanceObserver.
              (fn [list]
                (run!
                 (fn [entry]
                   (when (and (= "longtask" (.-entryType entry))
                              (> (.-duration entry) min-longtask-time))
                     (rx/push! subs
                               {::event :observer-longtask
                                :duration (.-duration entry)})))
                 (.getEntries list))))]
         (.observe observer #js {:entryTypes #js ["longtask"]})
         (fn []
           (.disconnect observer)))))
    (rx/empty)))

(defn- save-performance-info
  []
  (ptk/reify ::save-performance-info
    ptk/UpdateEvent
    (update [_ state]
      (letfn [(count-shapes [file]
                (->> file :data :pages-index
                     (reduce-kv
                      (fn [sum _ page]
                        (+ sum (count (:objects page))))
                      0)))
              (count-library-data [files {:keys [id]}]
                (let [data (dm/get-in files [id :data])]
                  {:components (count (:components data))
                   :colors (count (:colors data))
                   :typographies (count (:typographies data))}))]
        (let [file-id (get state :current-file-id)
              file (get-in state [:files file-id])
              file-size (count-shapes file)

              libraries
              (-> (refs/select-libraries (:files state) (:id file))
                  (d/update-vals (partial count-library-data (:files state))))

              lib-sizes