Add performance improvements to file thumbnails

Mainly addresing unnecesary object transmission. The new code strips
unnecesary data to be transferred from back to front.

Additionally it removes some legacy code and simplifies other
parts of code.
This commit is contained in:
Andrey Antukh 2022-03-21 09:25:19 +01:00 committed by Alonso Torres
parent 27c8f883ff
commit b91c42e186
6 changed files with 72 additions and 118 deletions

View file

@ -957,35 +957,23 @@
(let [selected (wsh/lookup-selected state)]
(rx/of (dch/update-shapes selected #(update % :blocked not)))))))
(defn extract-file-thumbnails-from-page
[state selected page]
(let [extract-frames (fn [page-id]
(let [objects (wsh/lookup-page-objects state page-id)]
(cph/get-frames objects)))
page-id (key page)
frames-with-thumbnail (->> (extract-frames page-id)
(filter (comp true? :file-thumbnail))
(map :id)
(remove #(some #{%} selected))
(map #(into {} {:id % :page-id page-id})))]
(when frames-with-thumbnail frames-with-thumbnail)))
(defn toggle-file-thumbnail-selected
[]
(ptk/reify ::toggle-file-thumbnail-selected
ptk/WatchEvent
(watch [_ state _]
(let [selected (wsh/lookup-selected state)
pages (get-in state [:workspace-data
:pages-index])
file-thumbnails (->> pages
(mapcat #(extract-file-thumbnails-from-page state selected %)))]
pages (-> state :workspace-data :pages-index vals)
extract (fn [{:keys [objects id] :as page}]
(->> (cph/get-frames objects)
(filter :file-thumbnail)
(map :id)
(remove selected)
(map (fn [frame-id] [id frame-id]))))]
(rx/concat
(rx/from
(for [ft file-thumbnails]
(dch/update-shapes [(:id ft)] #(update % :file-thumbnail not) (:page-id ft) nil)))
(rx/of (dch/update-shapes selected #(update % :file-thumbnail not))))))))
(rx/from (for [[page-id frame-id] (mapcat extract pages)]
(dch/update-shapes [frame-id] #(dissoc % :file-thumbnail) page-id nil)))
(rx/of (dch/update-shapes selected #(assoc % :file-thumbnail true))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Navigation

View file

@ -214,31 +214,6 @@
[:& shape-wrapper {:shape item
:key (:id item)}])))]]]))
(mf/defc file-thumbnail-svg
{::mf/wrap [mf/memo]}
[{:keys [data embed? include-metadata?] :as props
:or {embed? false include-metadata? false}}]
(let [data (assoc data :x 0 :y 0)
vbox (format-viewbox {:width (:width data 0) :height (:height data 0)})
background-color (get-in data [:options :background] default-color)]
[:& (mf/provider embed/context) {:value embed?}
[:& (mf/provider export/include-metadata-ctx) {:value include-metadata?}
[:svg {:view-box vbox
:version "1.1"
:xmlns "http://www.w3.org/2000/svg"
:xmlnsXlink "http://www.w3.org/1999/xlink"
:xmlns:penpot (when include-metadata? "https://penpot.app/xmlns")
:style {:width "100%"
:height "100%"
:background background-color}}
(when include-metadata?
[:& export/export-page {:options (:options data)}])
[:> shape-container {:shape data}
[:& frame/frame-thumbnail {:shape data}]]]]]))
(mf/defc frame-svg
{::mf/wrap [mf/memo]}
[{:keys [objects frame zoom show-thumbnails?] :or {zoom 1} :as props}]

View file

@ -31,36 +31,28 @@
(defn- request-thumbnail
[file-id]
(let [uri (u/join (cfg/get-public-uri) "api/rpc/query/file-data-for-thumbnail")
params {:file-id file-id
:strip-frames-with-thumbnails true}]
(->> (http/send!
{:method :get
:uri uri
:credentials "include"
:query params})
(let [uri (u/join (cfg/get-public-uri) "api/rpc/query/file-data-for-thumbnail")
params {:file-id file-id
:strip-frames-with-thumbnails true}
request {:method :get
:uri uri
:credentials "include"
:query params}]
(->> (http/send! request)
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response))))
(defonce cache (atom {}))
(defn render-frame
[data ckey]
(let [prev (get @cache ckey)]
(if (= (:data prev) data)
(:result prev)
(let [file-thumbnail (:file-thumbnail data)
elem (if file-thumbnail
(mf/element render/file-thumbnail-svg #js {:data file-thumbnail :width "290" :height "150"})
(mf/element render/page-svg #js {:data data :width "290" :height "150" :thumbnails? true}))
result (rds/renderToStaticMarkup elem)]
(swap! cache assoc ckey {:data data :result result})
result))))
[data]
(let [elem (if-let [frame (:thumbnail-frame data)]
(mf/element render/frame-svg #js {:objects (:objects data) :frame frame})
(mf/element render/page-svg #js {:data data :width "290" :height "150" :thumbnails? true}))]
(rds/renderToStaticMarkup elem)))
(defmethod impl/handler :thumbnails/generate
[{:keys [file-id] :as message}]
(->> (request-thumbnail file-id)
(rx/map
(fn [data]
{:svg (render-frame data #{file-id})
{:svg (render-frame data)
:fonts @fonts/loaded}))))