From bebe220aa0902e66fcb4610bb29fa9f004cec4e2 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 9 Aug 2019 15:07:16 +0000 Subject: [PATCH] :zap: Improve rendering performance. --- frontend/src/uxbox/main/data/workspace.cljs | 8 ++- frontend/src/uxbox/main/ui/workspace.cljs | 57 +++++++++---------- .../src/uxbox/main/ui/workspace/canvas.cljs | 4 +- .../src/uxbox/main/ui/workspace/rules.cljs | 8 ++- .../uxbox/main/ui/workspace/selection.cljs | 36 ++++++------ .../src/uxbox/main/ui/workspace/sidebar.cljs | 26 ++++----- .../main/ui/workspace/sidebar/drawtools.cljs | 6 +- .../main/ui/workspace/sidebar/layers.cljs | 4 +- .../main/ui/workspace/sidebar/options.cljs | 4 +- .../src/uxbox/main/ui/workspace/viewport.cljs | 11 ++-- 10 files changed, 83 insertions(+), 81 deletions(-) diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 8b9faf467..5af3edee3 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -120,7 +120,11 @@ ptk/UpdateEvent (update [_ state] (let [page-id (get-in state [:workspace :current])] - (update-in state [:workspace page-id :flags] conj flag)))) + (update-in state [:workspace page-id :flags] + (fn [flags] + (if (contains? flags flag) + flags + (conj flags flag))))))) (defn activate-flag [flag] @@ -574,7 +578,6 @@ ;; --- Apply Displacement (defrecord ApplyDisplacement [id] - udp/IPageUpdate ptk/WatchEvent (watch [_ state stream] (let [pid (get-in state [:workspace :current]) @@ -657,7 +660,6 @@ [] (StartMoveSelected.)) - ;; --- Start shape "edition mode" (defn start-edition-mode diff --git a/frontend/src/uxbox/main/ui/workspace.cljs b/frontend/src/uxbox/main/ui/workspace.cljs index a3a2f62f1..98e0990bd 100644 --- a/frontend/src/uxbox/main/ui/workspace.cljs +++ b/frontend/src/uxbox/main/ui/workspace.cljs @@ -35,7 +35,8 @@ [uxbox.main.user-events :as uev] [uxbox.util.data :refer [classnames]] [uxbox.util.dom :as dom] - [uxbox.util.geom.point :as gpt])) + [uxbox.util.geom.point :as gpt] + [uxbox.util.rdnd :as rdnd])) ;; --- Workspace @@ -77,8 +78,9 @@ (mf/defc workspace [{:keys [page wst] :as props}] - (let [flags (:flags wst) + (let [flags (mf/deref refs/flags) canvas (mf/use-ref* nil) + left-sidebar? (not (empty? (keep flags [:layers :sitemap :document-history]))) right-sidebar? (not (empty? (keep flags [:icons :drawtools @@ -87,6 +89,8 @@ :no-tool-bar-right (not right-sidebar?) :no-tool-bar-left (not left-sidebar?) :scrolling (:viewport-positionig workspace))] + (prn "workspace.render") + (mf/use-effect {:deps (:id page) :init #(subscibe canvas page) :end unsubscribe}) @@ -109,43 +113,34 @@ ;; Rules (when (contains? flags :rules) - [:& horizontal-rule {:zoom (:zoom wst)}]) + [:& horizontal-rule]) (when (contains? flags :rules) - [:& vertical-rule {:zoom (:zoom wst)}]) + [:& vertical-rule]) ;; Canvas - [:section.workspace-canvas {:id "workspace-canvas" - :ref canvas} - [:& viewport {:page page - :wst wst - :key (:id page)}]]] + [:section.workspace-canvas {:id "workspace-canvas" :ref canvas} + [:& viewport {:page page :key (:id page)}]]] ;; Aside (when left-sidebar? - [:& left-sidebar {:page page - :selected (:selected wst) - :flags (:flags wst)}]) + [:& left-sidebar {:page page :flags flags}]) (when right-sidebar? - [:& right-sidebar {:wst wst :page page}])]])) + [:& right-sidebar {:page page :flags flags}])]])) +(mf/defc workspace-page + [{:keys [project-id page-id] :as props}] + (let [page-iref (mf/use-memo {:deps #js [project-id page-id] + :init #(-> (l/in [:pages page-id]) + (l/derive st/state))}) + page (mf/deref page-iref)] -;; TODO: consider using `derive-state` instead of `key` for -;; performance reasons + (mf/use-effect + {:deps #js [project-id page-id] + :init #(st/emit! (dw/initialize project-id page-id))}) -(mf/def workspace-page - :mixins [mf/reactive] - :init - (fn [own {:keys [project-id page-id] :as props}] - (st/emit! (dw/initialize project-id page-id)) - (assoc own - ::page-ref (-> (l/in [:pages page-id]) - (l/derive st/state)) - ::workspace-ref (-> (l/in [:workspace page-id]) - (l/derive st/state)))) - :render - (fn [own props] - (let [wst (mf/react (::workspace-ref own)) - page (mf/react (::page-ref own))] - (when page - [:& workspace {:page page :wst wst}])))) + ;; (prn "workspace-page.render" (:id page) props) + + [:> rdnd/provider {:backend rdnd/html5} + (when page + [:& workspace {:page page}])])) diff --git a/frontend/src/uxbox/main/ui/workspace/canvas.cljs b/frontend/src/uxbox/main/ui/workspace/canvas.cljs index 4f65e6371..ab42c249b 100644 --- a/frontend/src/uxbox/main/ui/workspace/canvas.cljs +++ b/frontend/src/uxbox/main/ui/workspace/canvas.cljs @@ -13,8 +13,7 @@ [uxbox.main.ui.shapes :as uus] [uxbox.main.ui.workspace.drawarea :refer [draw-area]] [uxbox.main.ui.workspace.selection :refer [selection-handlers]] - [uxbox.util.geom.point :as gpt]) - (:import goog.events.EventType)) + [uxbox.util.geom.point :as gpt])) ;; --- Background @@ -32,7 +31,6 @@ (mf/defc canvas [{:keys [page wst] :as props}] - (prn "canvas") (let [{:keys [metadata id]} page zoom (:zoom wst 1) ;; NOTE: maybe forward wst to draw-area width (:width metadata) diff --git a/frontend/src/uxbox/main/ui/workspace/rules.cljs b/frontend/src/uxbox/main/ui/workspace/rules.cljs index 485ea7e83..00529b195 100644 --- a/frontend/src/uxbox/main/ui/workspace/rules.cljs +++ b/frontend/src/uxbox/main/ui/workspace/rules.cljs @@ -125,8 +125,10 @@ ;; --- Horizontal Rule (Component) (mf/defc horizontal-rule - [{:keys [zoom] :as props}] + {:wrap [mf/wrap-memo]} + [props] (let [scroll (mf/deref refs/workspace-scroll) + zoom (mf/deref refs/selected-zoom) scroll-x (:x scroll) translate-x (- (- c/canvas-scroll-padding) (:x scroll))] [:svg.horizontal-rule @@ -140,8 +142,10 @@ ;; --- Vertical Rule (Component) (mf/defc vertical-rule - [{:keys [zoom] :as props}] + {:wrap [mf/wrap-memo]} + [props] (let [scroll (mf/deref refs/workspace-scroll) + zoom (mf/deref refs/selected-zoom) scroll-y (:y scroll) translate-y (- (- c/canvas-scroll-padding) (:y scroll))] [:svg.vertical-rule diff --git a/frontend/src/uxbox/main/ui/workspace/selection.cljs b/frontend/src/uxbox/main/ui/workspace/selection.cljs index b458abacb..4704213fc 100644 --- a/frontend/src/uxbox/main/ui/workspace/selection.cljs +++ b/frontend/src/uxbox/main/ui/workspace/selection.cljs @@ -212,19 +212,19 @@ (geom/selection-rect))] [:& controls {:shape shape :zoom zoom :on-click on-click}])) -;; (mx/defc text-edition-selection-handlers -;; {:mixins [mx/static]} -;; [{:keys [id] :as shape} zoom] -;; (let [{:keys [x1 y1 width height] :as shape} (geom/selection-rect shape)] -;; [:g.controls -;; [:rect.main {:x x1 :y y1 -;; :width width -;; :height height -;; ;; :stroke-dasharray (str (/ 5.0 zoom) "," (/ 5 zoom)) -;; :style {:stroke "#333" -;; :stroke-width "0.5" -;; :stroke-opacity "0.5" -;; :fill "transparent"}}]])) +(mf/defc text-edition-selection-handlers + [{:keys [shape modifiers zoom] :as props}] + (let [{:keys [x1 y1 width height] :as shape} (-> (assoc shape :modifiers modifiers) + (geom/selection-rect))] + [:g.controls + [:rect.main {:x x1 :y y1 + :width width + :height height + ;; :stroke-dasharray (str (/ 5.0 zoom) "," (/ 5 zoom)) + :style {:stroke "#333" + :stroke-width "0.5" + :stroke-opacity "0.5" + :fill "transparent"}}]])) (def ^:private shapes-map-iref (-> (l/key :shapes) @@ -250,16 +250,18 @@ :modifiers modifiers :zoom zoom}] - ;; (and (= type :text) edition?) - ;; (-> (assoc shape :modifiers (get modifiers id)) - ;; (text-edition-selection-handlers zoom)) - + (and (= type :text) + (= edition? (:id shape))) + [:& text-edition-selection-handlers {:shape shape + :modifiers (get modifiers id) + :zoom zoom}] (and (= type :path) (= edition? (:id shape))) [:& path-edition-selection-handlers {:shape shape :zoom zoom :modifiers (get modifiers id)}] + :else [:& single-selection-handlers {:shape shape :modifiers (get modifiers id) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar.cljs index 0131db138..6e46c1a5a 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar.cljs @@ -20,7 +20,7 @@ (mf/defc left-sidebar {:wrap [mf/wrap-memo]} - [{:keys [flags selected page] :as props}] + [{:keys [flags page] :as props}] [:aside#settings-bar.settings-bar.settings-bar-left [:> rdnd/provider {:backend rdnd/html5} [:div.settings-bar-inside @@ -31,22 +31,18 @@ #_(when (contains? flags :document-history) (history-toolbox page-id)) (when (contains? flags :layers) - [:& layers-toolbox {:page page - :selected selected}])]]]) + [:& layers-toolbox {:page page}])]]]) ;; --- Right Sidebar (Component) (mf/defc right-sidebar - [{:keys [wst page] :as props}] - (let [flags (:flags wst) - dtool (:drawing-tool wst)] - [:aside#settings-bar.settings-bar - [:div.settings-bar-inside - (when (contains? flags :drawtools) - [:& draw-toolbox {:flags flags :drawing-tool dtool}]) - (when (contains? flags :element-options) - [:& options-toolbox {:page page - :selected (:selected wst)}]) - (when (contains? flags :icons) - #_(icons-toolbox))]])) + [{:keys [flags page] :as props}] + [:aside#settings-bar.settings-bar + [:div.settings-bar-inside + (when (contains? flags :drawtools) + [:& draw-toolbox {:flags flags}]) + (when (contains? flags :element-options) + [:& options-toolbox {:page page}]) + (when (contains? flags :icons) + #_(icons-toolbox))]]) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/drawtools.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/drawtools.cljs index b80ac6898..aa845e7b3 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/drawtools.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/drawtools.cljs @@ -12,6 +12,7 @@ [uxbox.main.data.shapes :as uds] [uxbox.main.data.workspace :as udw] [uxbox.main.data.workspace-drawing :as udwd] + [uxbox.main.refs :as refs] [uxbox.main.store :as st] [uxbox.main.user-events :as uev] [uxbox.util.i18n :refer (tr)] @@ -79,8 +80,9 @@ (mf/defc draw-toolbox {:wrap [mf/wrap-memo]} - [{:keys [flags drawing-tool] :as props}] + [{:keys [flags] :as props}] (let [close #(st/emit! (udw/toggle-flag :drawtools)) + dtool (mf/deref refs/selected-drawing-tool) tools (->> (into [] +draw-tools+) (sort-by (comp :priority second))) @@ -98,7 +100,7 @@ [:div.tool-window-close {:on-click close} i/close]] [:div.tool-window-content (for [[i props] (map-indexed vector tools)] - (let [selected? (= drawing-tool (:shape props))] + (let [selected? (= dtool (:shape props))] [:div.tool-btn.tooltip.tooltip-hover {:alt (tr (:help props)) :class (when selected? "selected") diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs index 52bb3bdb4..56631246e 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs @@ -13,6 +13,7 @@ [uxbox.main.data.pages :as udp] [uxbox.main.data.shapes :as uds] [uxbox.main.data.workspace :as udw] + [uxbox.main.refs :as refs] [uxbox.main.store :as st] [uxbox.main.ui.keyboard :as kbd] [uxbox.main.ui.shapes.icon :as icon] @@ -164,7 +165,8 @@ (mf/defc layers-toolbox [{:keys [page selected] :as props}] - (let [on-click #(st/emit! (udw/toggle-flag :layers))] + (let [on-click #(st/emit! (udw/toggle-flag :layers)) + selected (mf/deref refs/selected-shapes)] [:div#layers.tool-window [:div.tool-window-bar [:div.tool-window-icon i/layers] diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options.cljs index e85f6431a..6ab8a9198 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options.cljs @@ -15,6 +15,7 @@ [uxbox.main.data.workspace :as udw] [uxbox.main.geom :as geom] [uxbox.main.store :as st] + [uxbox.main.refs :as refs] [uxbox.main.ui.shapes.attrs :refer [shape-default-attrs]] [uxbox.main.ui.workspace.sidebar.options.circle-measures :as options-circlem] [uxbox.main.ui.workspace.sidebar.options.fill :as options-fill] @@ -110,7 +111,8 @@ (mf/defc options-toolbox {:wrap [mf/wrap-memo]} [{:keys [page selected] :as props}] - (let [close #(st/emit! (udw/toggle-flag :element-options))] + (let [close #(st/emit! (udw/toggle-flag :element-options)) + selected (mf/deref refs/selected-shapes)] [:div.elementa-options.tool-window [:div.tool-window-bar [:div.tool-window-icon i/options] diff --git a/frontend/src/uxbox/main/ui/workspace/viewport.cljs b/frontend/src/uxbox/main/ui/workspace/viewport.cljs index 4de880962..f0c48c38c 100644 --- a/frontend/src/uxbox/main/ui/workspace/viewport.cljs +++ b/frontend/src/uxbox/main/ui/workspace/viewport.cljs @@ -156,13 +156,14 @@ (events/unlistenByKey (::key3 own)) (dissoc own ::key1 ::key2 ::key3)) + :mixins [mf/reactive] + :render - (fn [own {:keys [page wst] :as props}] - (let [{:keys [drawing-tool tooltip zoom flags edition]} wst + (fn [own {:keys [page] :as props}] + (let [{:keys [drawing-tool tooltip zoom flags edition] :as wst} (mf/react refs/workspace) tooltip (or tooltip (get-shape-tooltip drawing-tool)) zoom (or zoom 1)] (letfn [(on-mouse-down [event] - (prn "viewport.on-mouse-down") (dom/stop-propagation event) (let [ctrl? (kbd/ctrl? event) shift? (kbd/shift? event) @@ -189,7 +190,6 @@ :ctrl? ctrl?}] (st/emit! (uev/mouse-event :up ctrl? shift?)))) (on-click [event] - (js/console.log "viewport.on-click" event) (dom/stop-propagation event) (let [ctrl? (kbd/ctrl? event) shift? (kbd/shift? event) @@ -216,8 +216,7 @@ :on-click on-click :on-double-click on-double-click :on-mouse-down on-mouse-down - :on-mouse-up on-mouse-up - } + :on-mouse-up on-mouse-up} [:g.zoom {:transform (str "scale(" zoom ", " zoom ")")} (when page [:& canvas {:page page :wst wst}])