⚡ Load the rasterizer iframe only when the SVG renderer needs it (#12835)

Create it once features say SVG, never in wasm mode. Also skip SVG frame
thumbnails in wasm mode.
This commit is contained in:
Elena Torró 2026-11-04 15:50:13 +01:00 committed by GitHub
parent 2f060e9baf
commit 4be8df5877
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 41 deletions

View File

@ -67,9 +67,10 @@
[]
(ptk/reify ::initialize-rasterizer
ptk/EffectEvent
(effect [_ _ _]
;; The rasterizer is used for the dashboard thumbnails
(thr/init!))))
(effect [_ state _]
;; Only the SVG renderer uses the rasterizer
(when-not (feat/active-feature? state "render-wasm/v1")
(thr/init!)))))
(defn initialize
[]
@ -107,9 +108,8 @@
(rx/map #(ws/initialize)))
(->> stream
(rx/filter (ptk/type? ::feat/initialize))
(rx/take 1)
(rx/map #(initialize-rasterizer)))))))
(rx/filter (comp #{::feat/initialize ::feat/recompute-features} ptk/type))
(rx/map initialize-rasterizer))))))
(defn ^:export init
[options]

View File

@ -961,11 +961,12 @@
component (ctkl/get-component data component-id)
page-id (:main-instance-page component)
root-id (:main-instance-id component)]
(if (and (= tag "component")
(features/active-feature? state "render-wasm/v1"))
(if (features/active-feature? state "render-wasm/v1")
;; WASM: render immediately, UI only — server persist happens
;; on the debounced path (update-component-thumbnail)
(dwt.wasm/render-thumbnail file-id page-id root-id)
;; on the debounced path (update-component-thumbnail). Frame
;; thumbnails are only shown by the SVG viewport.
(when (= tag "component")
(dwt.wasm/render-thumbnail file-id page-id root-id))
(dwt/update-thumbnail file-id page-id root-id tag "update-component-thumbnail-sync"))))
(defn- render-component-thumbnail-event

View File

@ -25,6 +25,7 @@
(defonce ready? false)
(defonce queue #js [])
(defonce instance nil)
(defonce started? false)
(defonce msgbus (rx/subject))
(defonce origin
(-> cf/rasterizer-uri
@ -32,6 +33,7 @@
(dm/str)))
(declare send-message!)
(declare init!)
(defn- process-queued-messages!
[]
@ -86,6 +88,8 @@
:scope "penpot/rasterizer"
:payload payload}]
(init!)
(if ^boolean ready?
(send-message! message)
(queue-message! message))
@ -108,39 +112,42 @@
(render {:data data :styles styles :width width :result result})))
(defn init!
"Initializes the rasterizer."
"Creates the rasterizer iframe once. It is only needed by the SVG
renderer, so sessions with render-wasm never load it."
[]
(let [iframe (dom/create-element "iframe")]
(dom/set-attribute! iframe "id" "rasterizer")
(dom/set-attribute! iframe "src" origin)
(dom/set-attribute! iframe "hidden" true)
(.addEventListener js/window "message" on-message)
(->> (http/fetch {:method :head
:uri cf/rasterizer-uri
:mode :no-cors})
(rx/map (fn [response]
(let [allowed? (not (.-redirected response))]
(when-not allowed?
(log/err :hint "rasterizer iframe blocked by adblocker" :origin origin))
allowed?)))
(rx/catch (fn [cause]
(log/err :hint "rasterizer iframe blocked by adblocker" :origin origin :cause cause)
(rx/of false)))
(when-not ^boolean started?
(set! started? true)
(let [iframe (dom/create-element "iframe")]
(dom/set-attribute! iframe "id" "rasterizer")
(dom/set-attribute! iframe "src" origin)
(dom/set-attribute! iframe "hidden" true)
(.addEventListener js/window "message" on-message)
(->> (http/fetch {:method :head
:uri cf/rasterizer-uri
:mode :no-cors})
(rx/map (fn [response]
(let [allowed? (not (.-redirected response))]
(when-not allowed?
(log/err :hint "rasterizer iframe blocked by adblocker" :origin origin))
allowed?)))
(rx/catch (fn [cause]
(log/err :hint "rasterizer iframe blocked by adblocker" :origin origin :cause cause)
(rx/of false)))
(rx/subs! (fn [allowed?]
(if allowed?
(do
(dom/append-child! js/document.body iframe)
(set! instance iframe))
(rx/subs! (fn [allowed?]
(if allowed?
(do
(dom/append-child! js/document.body iframe)
(set! instance iframe))
(let [new-origin (-> cf/public-uri
(u/join "rasterizer.html")
(dm/str))]
(log/warn :hint "fallback to main domain" :origin new-origin)
(let [new-origin (-> cf/public-uri
(u/join "rasterizer.html")
(dm/str))]
(log/warn :hint "fallback to main domain" :origin new-origin)
(dom/set-attribute! iframe "src" new-origin)
(dom/append-child! js/document.body iframe)
(dom/set-attribute! iframe "src" new-origin)
(dom/append-child! js/document.body iframe)
(set! origin new-origin)
(set! cf/rasterizer-uri cf/public-uri)
(set! instance iframe))))))))
(set! origin new-origin)
(set! cf/rasterizer-uri cf/public-uri)
(set! instance iframe)))))))))