Inline svg vs svg Sprite vs multiple external files

4.3k views Asked by At

OK so i am building a web app using Laravel & Vue js mainly. I tried to use https://github.com/JetBrains/svg-sprite-loader#installation but the exported svg shows up blank.

In that context before proceeding, i started wondering if this is really worth it and tbh, i am not sure.

So my question is, what is really the difference?

Let's assume we can't use icon fonts, because we want to have multicoloured svgs.

  • Is it even worth trying to use a package to merge the svgs into a sprite and then use it, or does it not really make a difference with http/2?

  • Considering file size and data usage, is it worth trying to minimise this aspect using sprite instead of multiple external svg files?

  • Inlining the svgs is also an option but this would dramatically increase the dom size.

So i am left wondering... has anyone tried out all these techniques and figured out the best and most performant one and what are their true differences.

Lastly if anyone would give me some input on why my svg sprite shows blank, it would be a huge bonus :P

I have configured the above package in my webpack.mix like so:

const mix = require('laravel-mix');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .webpackConfig({
        module: {
            rules: [
                {
                    test: /resources\/images\/.*\.svg$/,
                    loader: 'svg-sprite-loader',
                    exclude: /node_modules/,
                    options: {
                        extract: true,
                        spriteFilename: 'icons-sprite.svg',
                        publicPath: 'images/sprites/',
                    }
                }
            ]
        },
        plugins: [
            new SpriteLoaderPlugin({ plainSprite: true}) // Sprites Plugin.
        ],
    })
    .version()

1

There are 1 answers

4
Danny '365CSI' Engelman On

Is it even worth trying to use a package to merge the svgs into a sprite and then use it, or does it not really make a difference with http/2?

It does matter, but depends on your use case. You would have to test on your production environment yourself. Ofcourse HTTP/2 is always better

Considering file size and data usage, is it worth trying to minimise this aspect using sprite instead of multiple external svg files?

same answer as 1.. Use Case. Comes down to estimating (because you can't calculate it) how long Browser A has to wait for new content.

GZip is the most important factor for data usage.

On slow 3G connections adding your own LZMA compression for (large) files could be interesting.

Inlining the svgs is also an option but this would dramatically increase the dom size.

You are still sending the same bytes, only in a different file, might even be better because of GZip working on everything in one file.

In general my advice is to not worry about performance; it is not an OR-OR decision.

Start with seperate files, only re-factor when you hit performance issues.
Maybe develop with refactoring in mind if you expect performance issues.

Alternative: Create SVG Client Side

I went one step further. Became an experiment how small/fast I could go:

  • Reworked all SVG to String notation <circle cx='20' cy='20' r='5'/> becomes c:20,20,5
  • Used in one JS file
  • parse the Strings Client Side
  • to create SVG
  • used in a DataURI IMG src

This got 550 KB in 52 SVG files down to 16 KB in one Custom Element file

and GZip is an important factor!

GZip compresses the Server side file before it is send to the Client.

Yes minification is important, but minification can have a negative effect on GZip compression.

Good read from a long time ago:

https://encode.su/threads/1889-gzthermal-pseudo-thermal-view-of-Gzip-Deflate-compression-efficiency

It explains why <!DOCTYPE HTML> is bad, and <!doctype html> is good.

The same applies to SVG files: <circle ... is better than <CIRCLE ...

and

<circle fill='...' cx='20' .../> is better than <circle cx='20' ... fill='...'/>

Because GZip finds a longer repeating pattern <circle fill='