immersive-web / cardboard-vr-display

A JavaScript implementation of a WebVR 1.1 VRDisplay
https://immersive-web.github.io/cardboard-vr-display
Apache License 2.0
92 stars 43 forks source link

Optimize rotate instructions SVG #31

Closed MattiasBuelens closed 5 years ago

MattiasBuelens commented 5 years ago

The base64-encoded SVG in src/assets/rotate-instructions.js takes up ~52 KB. The total bundle weighs in at 185 KB, so this single SVG accounts for 28% of the total bundle size. This is quite significant, and can be made much smaller with just a few easy changes.

Here's what I've done:

  1. Decode the base64 to get the original SVG.
  2. Optimize the SVG using SVGOMG. (Default settings + "remove ")</li> <li>Replace double quotes <code>"</code> with single quotes <code>'</code>. (This avoids having to escape quotes when pasting in a double-quoted JS string literal.)</li> <li>Paste the result into the JS file.</li> </ol> <p>To create a valid data URI, I replaced <code>Util.base64</code> with a <code>Util.dataUri</code> helper function. This function creates a data URI for a <strong>non-base64-encoded</strong> payload. Instead, it simply escapes any URL-unsafe characters in the payload. For more about this technique, see these blog posts by <a rel="noreferrer nofollow" target="_blank" href="https://css-tricks.com/probably-dont-base64-svg/">Chris Coyier</a> and <a rel="noreferrer nofollow" target="_blank" href="https://codepen.io/tigt/post/optimizing-svgs-in-data-uris">Taylor Hunt</a>.</p> <p>As a result, the SVG weighs in at only ~24 KB, and the total bundle size drops to 157 KB. That's 28 KB less to download. 😄 </p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/jsantell"><img src="https://avatars.githubusercontent.com/u/641267?v=4" />jsantell</a> commented <strong> 5 years ago</strong> </div> <div class="markdown-body"> <p>Thank you for this! I've wanted this for some time. I'll check this out in a bit, and happy to have the SVG source back in the repo. I can imagine in the future, adding a rollup svg plugin for this as well. Are there any advantages of continuing using the SVG as an image source rather than inline at this point that you're aware of?</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/MattiasBuelens"><img src="https://avatars.githubusercontent.com/u/649348?v=4" />MattiasBuelens</a> commented <strong> 5 years ago</strong> </div> <div class="markdown-body"> <blockquote> <p>I can imagine in the future, adding a rollup svg plugin for this as well.</p> </blockquote> <p>Unfortunately, <a href="https://www.npmjs.com/package/rollup-plugin-svg"><code>rollup-plugin-svg</code></a> creates a base64 data URI... 😕 We could use <a href="https://www.npmjs.com/package/rollup-plugin-string"><code>rollup-plugin-string</code></a> instead to import the SVG file as a string (basically what <code>rotate-instructions.js</code> now does manually).</p> <blockquote> <p>Are there any advantages of continuing using the SVG as an image source rather than inline at this point that you're aware of?</p> </blockquote> <p>Good point, hadn't even though of that. As far as I know, inline SVG works just fine. We can just <code>.innerHTML = svgString</code> and we're done. 😛 </p> <p>Do you want me to try these things out in this PR?</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/jsantell"><img src="https://avatars.githubusercontent.com/u/641267?v=4" />jsantell</a> commented <strong> 5 years ago</strong> </div> <div class="markdown-body"> <p>@MattiasBuelens It's been working OK previously, so if this cuts down the size by 28k, that sounds great to me! Thank you for this improvement, I'll push this upstream to the webvr/webxr polyfills shortly</p> </div> </div> <div class="page-bar-simple"> </div> <div class="footer"> <ul class="body"> <li>© <script> document.write(new Date().getFullYear()) </script> Githubissues.</li> <li>Githubissues is a development platform for aggregating issues.</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script> <script src="/githubissues/assets/js.js"></script> <script src="/githubissues/assets/markdown.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/highlight.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/languages/go.min.js"></script> <script> hljs.highlightAll(); </script> </body> </html>