From 5ecf9245b32faba781fd823f5812d156b874182a Mon Sep 17 00:00:00 2001
From: stuebinm <stuebinm@disroot.org>
Date: Thu, 10 Mar 2022 01:20:20 +0100
Subject: [PATCH] mutate the svg in-place

this changes the update() function to mutate the svg in-place instead of
re-serialising and then letting the browser re-parse it each time, which
avoids (a) having to copy the entire svg object (including the font blob
as string) and (b) having to first serialise and then parse it
again (also including the blob).

The result is text editing with no discernable delay while typing.

This does mean that the svg is now embedded directly and may e.g. share
its id namespace, though that doesn't appear to be a problem with the
current template and also shouldn't be a problem in general as long as
the svg itself isn't user-generated.
---
 src/index.html | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/index.html b/src/index.html
index 5b13947..b1dfd52 100644
--- a/src/index.html
+++ b/src/index.html
@@ -83,6 +83,11 @@
         #preview_big, #preview_small {
             display: block;
             width: 100%;
+            /* TODO this is eyeballed and might not work for all
+            /  screen / font sizes; unfortunately svg-element's dont
+            /  resize to content automatically (and I'm not sure if
+            /  they can) */
+            height: 30em;
         }
         @media screen and (prefers-color-scheme: light) {
             body {
@@ -173,9 +178,10 @@
             }
 
             update_logo = () => {
-                // Might at least try to be a bit immutable
-                svg_big = svg_big_template.cloneNode(true);
-                svg_small = svg_small_template.cloneNode(true);
+                // don't copy this each time
+                // (unfortunately we're not in a lazy language … *sigh*)
+                svg_big = svg_big_template //.cloneNode(true);
+                svg_small = svg_small_template //.cloneNode(true);
 
                 // Collect all options
                 animal_selected = document.querySelector('#selector_animal input[name=animal]:checked').value;
@@ -200,9 +206,6 @@
                 apply_color(".color_background_top", "stop-color", background_color.top);
                 apply_color(".color_background_bottom", "stop-color", background_color.bottom);
 
-                // Display the SVG in the preview, it's incoded to prevent id conflics and make shure it's displayed correctly
-                document.querySelector("#preview_big").src = "data:image/svg+xml;base64," + btoaUnicode(new XMLSerializer().serializeToString(svg_big));
-                document.querySelector("#preview_small").src = "data:image/svg+xml;base64," + btoaUnicode(new XMLSerializer().serializeToString(svg_small));
 
                 // Generate a simple alt text
                 document.querySelector("#alt_text").innerHTML = "Stylized logo showing a " + animal_selected + " in a bubble. The text underneath reads \"" + headline_text + "\" and \"" + sub_headline_texts.join(" ") + "\".";
@@ -211,6 +214,12 @@
             }
             update_logo();
 
+            // don't replace the entire svg each time, just add it once as svg, then
+            // mutate it in place; that way the browser can just ignore the font blob
+            // after it's been loaded once
+            document.querySelector("#preview_big").appendChild (svg_big);
+            document.querySelector("#preview_small").appendChild(svg_small);
+
             // Add a event listener to every input event
             document.querySelectorAll(
                 "#selector_animal input,\
@@ -274,13 +283,13 @@
                 <h2>big</h2>
                 <button id="download_big_svg">Save big SVG</button>
                 <button id="download_big_png">Save big PNG</button>
-                <img id="preview_big"/>
+                <svg id="preview_big"/>
             </div>
             <div>
                 <h2>small</h2>
                 <button id="download_small_svg">Save small SVG</button>
                 <button id="download_small_png">Save small PNG</button>
-                <img id="preview_small"/>
+                <svg id="preview_small"/>
             </div>
         </div>
         <h2>Alt text</h2>
-- 
GitLab