0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-13 00:01:51 -05:00

🎉 Add better profiling helpers.

This commit is contained in:
Andrey Antukh 2020-04-08 22:49:18 +02:00
parent 9db6be2047
commit bbbd7b704e
2 changed files with 48 additions and 22 deletions

View file

@ -1035,6 +1035,7 @@
;; --- Duplicate Selected ;; --- Duplicate Selected
;; TODO: handle properly naming
(defn duplicate-shapes (defn duplicate-shapes
[shapes] [shapes]
@ -1120,7 +1121,6 @@
(and (pos? (count shapes)) (and (pos? (count shapes))
(every? shape? shapes)) (every? shape? shapes))
;; (rx/of (duplicate-shapes shapes))
(rx/of (duplicate-shapes selected)) (rx/of (duplicate-shapes selected))
:else :else

View file

@ -2,12 +2,29 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;; ;;
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz> ;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.util.perf (ns uxbox.util.perf
"Performance and debugging tools." "Performance profiling for react components."
#?(:cljs (:require-macros [uxbox.util.perf])) #?(:cljs (:require-macros [uxbox.util.perf]))
#?(:cljs (:require [uxbox.util.math :as math]))) #?(:cljs (:require [uxbox.util.math :as math]
[rumext.alpha :as mf]
[goog.functions :as f]
["react" :as react]
["tdigest" :as td])))
;; For use it, just wrap the component you want to profile with
;; `perf/profiler` component and pass a label for debug purpose.
;;
;; Example:
;;
;; [:& perf/profiler {:label "viewport"}
;; [:section
;; [:& some-component]]]
;;
;; This will catch all renders and print to the console the
;; percentiles of render time measures. The log function is
;; automatically debouced for avod excesive spam to the console.
#?(:clj #?(:clj
(defmacro with-measure (defmacro with-measure
@ -20,23 +37,32 @@
res#))) res#)))
;; id, // the "id" prop of the Profiler tree that has just committed #?(:cljs
;; phase, // either "mount" (if the tree just mounted) or "update" (if it re-rendered) (defn on-render-factory
;; actualDuration, // time spent rendering the committed update [label]
;; baseDuration, // estimated time to render the entire subtree without memoization (let [buf (td/TDigest.)
;; startTime, // when React began rendering this update log (f/debounce
;; commitTime, // when React committed this update (fn [phase buf]
;; interactions // the Set of interactions belonging to this update (js/console.log (str "[profile: " label " (" phase ")] "
"samples=" (unchecked-get buf "n") "\n"
"Q50=" (.percentile buf 0.50) "\n"
"Q75=" (.percentile buf 0.75) "\n"
"Q95=" (.percentile buf 0.90) "\n"
"MAX=" (.percentile buf 1))))
300)]
(fn [id phase adur, bdur, st, ct, itx]
(.push buf adur)
(log phase buf)))))
#?(:cljs #?(:cljs
(defn react-on-profile (mf/defc profiler
[] {::mf/wrap-props false}
(let [sum (volatile! 0) [props]
ctr (volatile! 0)] (let [children (unchecked-get props "children")
(fn [id phase adur, bdur, st, ct, itx] label (unchecked-get props "label")
(vswap! sum (fn [prev] (+ prev adur))) on-render (mf/use-memo
(vswap! ctr inc) (mf/deps label)
(js/console.log (str "[profile:" id ":" phase "]") #(on-render-factory label))]
"" [:> react/Profiler {:id label
(str "time=" (math/precision adur 4)) :on-render on-render}
(str "avg=" (math/precision (/ @sum @ctr) 4))))))) children])))