📝 SVG Icon Optimization #
We will have a look at SVG Icon optimization, in this Deno Fresh SVG sprites post. Without care, SVG icons can take up half of the bytes of HTML code shipped for a particular page. This is especially true working in React and embedding the SVG inline, in React components.
In this post, we will see how you can create an SVG sprite sheet for all icons on a page, or a
site. Loading that sheet as an independent, resource from an HTML use
tag is a more performant alternative than adding the SVG content inline. We shall see, this approach
also allows you easily to style the icons.
We see further optimizations, making the sprite sheet a static asset with Deno Fresh’s cache-busting feature. Finally, you get some example code for using the SVGO plugin in Deno to minify the sprite sheet. Hopefully, this is what you were looking for, so let’s get going. The code and approach is based on an excellent blog post by Ben Adam , which goes into the details of how it works together with limitations. We won’t revisit those aspects here.
🧱 What are we Building? #
I put together a basic demo for the post, though you should be able just to copy and paste code snippets into a new or existing project, which you are already working on. There is a link to the full demo code further down.
Using these techniques, I reduced the size of shipped HTML by more than 25% (after compression) for a site I was working on.
🔎 Finding Icons #
If you are not new here, you probably already know that Icônes by Anthony Fu is my “go to” source of SVG icons. It is a huge library with dozens of icon collections, and you are unlikely to be unable to find any icon you are looking for there.
Although Icônes provides downloadable React components for each icon, here we need the raw SVG. To get going, go to the Icônes all-collection search page to find and select an icon.
When you select your chosen icon, a pop-up will appear at the bottom of the window with the various format options. From Snippets, select SVG. This will copy the SVG code to your clipboard.
Example SVG Icon Code #
Here is the SVG code for the Simple Icons Deno icon (used in the example image above):
You can see the full SVG for just one, simple icon is already a fair few bytes! In the next section, we start building the component which pulls in the path from a sprite sheet, rather than inlining it.
🧩 Creating an SVG Component with use
Element #
Here is the code for a Preact component, which will produce the SVG icon above. The file path in
the demo code is components/Icons/Deno.tsx
:
Following Ben’s method, the Preact component is an HTML use
tag
sandwiched inside an SVG tag. We can include styles on the SVG tag, and the path will go into the sprite
sheet. The final sprite sheet will be a static asset in the static
directory of the project. deno
id
in the href
path is our own identifier,
used to pick the right icon from the sprite sheet.
The Deno Fresh cache-busting comes from wrapping our path in the asset
function (imported from $fresh/runtime
in line 1
). Deno will add a hash to the end of the path in the output site. This lets us set a long cache
time, since the path will change whenever the sprite sheet changes, and the new sheet will be
fetched, rather than recycling any cached version.
🥤 Adding the SVG Icon to the Sprite Sheet #
The base sprite template will look like this (file path is assets/sprite.svg
in the demo code):
We will add each icon as a symbol
element, with id
inside the defs
element. In the next section, we optimize this file
and output the optimized version to static/sprite.svg
. Here is the
completed version with a couple of icons:
Notice:
-
in lines
6
and14
, we use theviewBox
values from the source SVG; -
we place the
path
elements inside thesymbol
tag; and -
we must remember to add an
id
matching theid
given in the corresponding component.
If your SVG has a defs
tag, just include the icon’s defs
tag contents above the symbol
element for your icon.
🔥 Optimizing the Sprite #
As a final step, you can add a Deno script to optimize the static, served sprite. First, update deno.json
:
Then create the script minify-svg-sprite.ts
in the project root directory:
The plugins config here is important. Without it, SVGO will optimize away the SVG needed for your icons.
You can now use the SVG icon components on your site pages:
🗳 Poll #
💯 Deno Fresh SVG Sprites: Checking Your Work #
Run the minify script, and check it outputs a minified version of the sprite to static/sprite.svg
. Remember to re-run this script whenever you add new icons to the sprite.
If you pull open dev tools and have a look at the Network tab, you should see the
sprite is downloaded. The path should have a hash on the end of it (something like sprite.svg?__frsh_c=8d89...
).
Jumping onto the Inspector tab, use should find a use
element, instead of the inline SVG code for the icon (though you can expand the enclosed #shadow-root
to inspect the SVG included from the sprite).
🙌🏽 Deno Fresh SVG Sprites: Wrapping Up #
We saw how you can set up Deno Fresh SVG Sprites in your own project. In particular, we saw:
- how you can use Icônes to find SVG icons;
- how you make sure create an SVG sprite sheet for use with Preact components; and
- a way to optimize SVG assets in Deno.
The complete code for this post . I do hope the post has either helped you with an existing project or provided some inspiration for getting started with setting up a new one.
Get in touch if you have some questions about this content or suggestions for improvements. You can add a comment below if you prefer. Also, reach out with ideas for fresh content on Deno or other topics!
🏁 Deno Fresh SVG Sprites: Summary #
What is a performant way to add SVG icons in Deno Fresh? #
- Creating an SVG sprite sheet is an efficient way to add SVG icons to your Deno Fresh site. Using this approach, you can also style the icons, changing colours or sizes, for example. We saw you can create an SVG sprite sheet as a static asset. That sprite sheet will include the SVG icons, where each icon has an id. In your icon component, you will add a `use` element, in place of the inline SVG path, setting the use tag href attribute to the sprite sheet URL (with the id tacked onto the end).
How does Deno cache-busting work? #
- To cache bust static assets in Deno, first create a special URL with the asset function. You can import it as a named import from `$fresh/runtime` and it takes a single argument of the path of the asset (which will already be in the `static` folder of your project). When Deno generates the site, it computes a hash of the static assets and adds this as a query parameter on the URL for the asset. You can now set a long expiry for caching the asset. As the URL includes the hash, whenever the asset contents change, the URL also changes, meaning the new asset has to be downloaded, forsaking the cached version.
Does SVGO work with Deno? #
- Yes, you can include it in your import map as `https://esm.sh/svgo@3.0.2/`, for example. From there you can use it in any SVG minifying scripts you have.
🙏🏽 Deno Fresh SVG Sprites: Feedback #
Have you found the post useful? Would you prefer to see posts on another topic instead? Get in touch with ideas for new posts. Also, if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, then please consider supporting me through Buy me a Coffee.
Just dropped a new post on adding SVG logo sprites in 🍋 Deno Fresh, which:
— Rodney (@askRodney) July 12, 2023
- lets you style icons in Preact,
- reduces shipped HTML vs. adding inline SVG
We also look at minifying and cache-busting the sprites.
Hope you find it useful!
#learndenohttps://t.co/td5EA5nuya
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter, @rodney@toot.community on Mastodon and also the #rodney Element Matrix room. Also, see further ways to get in touch with Rodney Lab. I post regularly on Astro as well as Deno. Also, subscribe to the newsletter to keep up-to-date with our latest projects.