From b616a20b28fd410946a3a65859869932ab2713f7 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 28 Jul 2023 16:38:28 +0200 Subject: [PATCH] :zap: Add performance oriented refactor to the outline component --- .../main/ui/workspace/viewport/outline.cljs | 116 ++++++++++-------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/viewport/outline.cljs b/frontend/src/app/main/ui/workspace/viewport/outline.cljs index 9cad0c7326..49b893a1df 100644 --- a/frontend/src/app/main/ui/workspace/viewport/outline.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/outline.cljs @@ -7,8 +7,10 @@ (ns app.main.ui.workspace.viewport.outline (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.exceptions :as ex] [app.common.geom.shapes :as gsh] + [app.common.pages.helpers :as cph] [app.common.types.container :as ctn] [app.main.refs :as refs] [app.main.ui.hooks :as hooks] @@ -16,83 +18,95 @@ [app.util.object :as obj] [app.util.path.format :as upf] [clojure.set :as set] - [rumext.v2 :as mf] - [rumext.v2.util :refer [map->obj]])) + [rumext.v2 :as mf])) (mf/defc outline {::mf/wrap-props false} [props] - (let [shape (obj/get props "shape") - zoom (obj/get props "zoom" 1) - modifier (obj/get props "modifier") + (let [shape (unchecked-get props "shape") + modifier (unchecked-get props "modifier") - shape (gsh/transform-shape shape (:modifiers modifier)) + zoom (d/nilv (unchecked-get props "zoom") 1) + shape (gsh/transform-shape shape (:modifiers modifier)) transform (gsh/transform-str shape) - path? (= :path (:type shape)) - path-data - (mf/use-memo - (mf/deps shape) - #(when path? - (or (ex/ignoring (upf/format-path (:content shape))) - ""))) - - ;; Note that we don't use mf/deref to avoid a repaint dependency here - objects (deref refs/workspace-page-objects) + ;; NOTE: that we don't use mf/deref to avoid a repaint dependency here + objects (deref refs/workspace-page-objects) color (if (ctn/in-any-component? objects shape) "var(--color-component-highlight)" "var(--color-primary)") - {:keys [x y width height selrect]} shape + x (dm/get-prop shape :x) + y (dm/get-prop shape :y) + width (dm/get-prop shape :width) + height (dm/get-prop shape :height) + selrect (dm/get-prop shape :selrect) + type (dm/get-prop shape :type) + content (get shape :content) + path? (cph/path-shape? shape) - border-radius-attrs (attrs/extract-border-radius shape) + path-data + (mf/with-memo [path? content] + (when (and ^boolean path? (some? content)) + (d/nilv (ex/ignoring (upf/format-path content)) ""))) - path? (some? (.-d border-radius-attrs)) + border-attrs + (attrs/extract-border-radius shape) - outline-type (case (:type shape) - :circle "ellipse" - :path "path" - (if path? "path" "rect")) + outline-type + (case type + :circle "ellipse" + :path "path" + (if (some? (obj/get border-attrs "d")) + "path" + "rect")) - common {:fill "none" - :stroke color - :strokeWidth (/ 2 zoom) - :pointerEvents "none" - :transform transform} + props + (obj/merge! + #js {:fill "none" + :stroke color + :strokeWidth (/ 2 zoom) + :pointerEvents "none" + :transform transform} - props (case (:type shape) - :circle - {:cx (+ x (/ width 2)) - :cy (+ y (/ height 2)) - :rx (/ width 2) - :ry (/ height 2)} + (case type + :circle + #js {:cx (+ x (/ width 2)) + :cy (+ y (/ height 2)) + :rx (/ width 2) + :ry (/ height 2)} - :path - {:d path-data - :transform nil} + :path + #js {:d path-data + :transform nil} - {:x (:x selrect) - :y (:y selrect) - :width (:width selrect) - :height (:height selrect) - :rx (.-rx border-radius-attrs) - :ry (.-ry border-radius-attrs) - :d (.-d border-radius-attrs)})] + (let [x (dm/get-prop selrect :x) + y (dm/get-prop selrect :y) + w (dm/get-prop selrect :width) + h (dm/get-prop selrect :height)] + #js {:x x + :y y + :width w + :height h + :rx (obj/get border-attrs "rx") + :ry (obj/get border-attrs "ry") + :d (obj/get border-attrs "d")}))) + ] - [:> outline-type (map->obj (merge common props))])) + [:> outline-type props])) (mf/defc shape-outlines-render {::mf/wrap-props false ::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "zoom" "modifiers"]))]} [props] - - (let [shapes (obj/get props "shapes") - zoom (obj/get props "zoom") - modifiers (obj/get props "modifiers")] + (let [shapes (unchecked-get props "shapes") + zoom (unchecked-get props "zoom") + modifiers (unchecked-get props "modifiers")] (for [shape shapes] - (let [modifier (get modifiers (:id shape))] - [:& outline {:key (str "outline-" (:id shape)) + (let [shape-id (dm/get-prop shape :id) + modifier (get modifiers shape-id)] + [:& outline {:key (dm/str "outline-" shape-id) :shape shape :modifier modifier :zoom zoom}]))))