13

I have a webpage that is full of inline-SVG around 140+ inline SVGs! Just the HTML file size is 23MB, plus there is external CSS and JavaScript loading, though that is roughly only around 30KB. The real deal is the HTML file itself with thousands of lines of code mostly consisting of SVGs.

My webpage takes 2-3 minutes to load up on my (probably) average internet, how can I reduce the loading time while especially reducing the file size of the HTML file? I don't think using separate SVG files for the images would be any better because that would take even more time to load because of separate HTTP requests.

Is there any way for me to shorten the loading time from the current 2-3 minutes to under 5 seconds?

A small screenshot from the Networks panel in Chrome Dev Tools:

enter image description here

16
  • 7
    What are the reasons for needing SVG? This smells like an XY problem. Commented Sep 22, 2021 at 0:09
  • 3
    @Harper-ReinstateMonica The reason I thought using inline-SVG would be better was that a lot of PNG images might have been larger and size and would also cause many HTTP requests (I did not know about lazy loading at that time). Commented Sep 22, 2021 at 8:42
  • 5
    Well, I resisted the urge lol... but still that's an XY, because you could have asked about that. Always remember any problem you have, a million web designers have also had, and some of them are the people who design web standards. They have spent 25 years optimizing browsers and altering web standards to solve problems just like that. Never assume they didn't :) Commented Sep 22, 2021 at 17:31
  • 2
    I didn't. Just learn the secret of the XY problem and you'll solve problems more easily! Point being, you're not alone, you have lots of help! Commented Sep 22, 2021 at 18:02
  • 1
    @SyedMohammadSannan Having a bunch of PNG icons would be better than using SVGs in this case, for a number of reasons. The PNG files would have been smaller in size than the SVG files, not larger. The HTTP requests concern is also unfounded, since PNG files can be inlined like SVGs can (though inlining would still be unnecessary and possibly detrimental on the whole). It seems to me like you made several incorrect assumptions coming into this question. I am glad the thread helped you anyways, though! Commented Sep 22, 2021 at 19:06

2 Answers 2

42
+200

From what you've stated in the comments (now chat), I understand that you cannot reduce the size of these SVG files, you cannot replace them with thumbnails (e.g. small png files), and you cannot split them up onto multiple pages. In other words you are stuck with a web page that has 23MB worth of SVG files on it, and there's no way to change that.

That leaves you with only a few options left:

  1. Make sure your server is properly compressing these files using gzip or brotli compression. You can check whether your server is properly compressing these files by following this Stack Overflow answer. SVGs are highly compressible, so this is a critical step. This alone could improve loading time by over 50%, if your server is not already doing this.

  2. Make sure these SVG files are properly optimized and minified, using something like svgo (and SVGOMG gui). This could save maybe another 20-40%.

  3. Consider linking the SVG files externally by using img tags, and use the loading: lazy directive on them. Then, at least the loading of the images will be deferred until the user scrolls down the page. (If, as you stated in the comments, your images are not initially visible in the viewport but are later shown dynamically by JavaScript, loading: lazy should still prevent them from loading until they are viewed, because it "Defers loading the image until it reaches a calculated distance from the viewport, as defined by the browser." Alternatively, you can modify your JavaScript to prevent the SVG tag from loading in at all until the script is triggered.)

If you link the SVG files externally by using img tags, that also has the added benefit of letting your HTML load to completion before the SVG files begin loading in. So parts of your HTML that are located below the SVG embeds in the document, like the footer, will load in before the SVGs finish.

To answer your concern about external SVG files generating separate HTTP requests that increase load time, this is not something you should need to worry about if your server supports HTTP/2 (so follow this Stack Overflow solution to double check that it's enabled). If so, all requests will be multiplexed over a single TCP connection.

21
  • 4
    @SyedMohammadSannan Gzip and brotli compression are settings that you can enable in your server software (Apache, nginx, or your CDN). It compresses files on the server before it sends them to the browser. You'll want to check that your web page requests are being served using gzip or brotli. Commented Sep 20, 2021 at 20:22
  • 3
    @SyedMohammadSannan The "data" protocol is just telling you that they're inline rather than separate files / HTTP requests. If you've decided to keep them inline, then the important thing to check is the 23MB of HTML - if that one's compressed, then the SVGs inlined within it are compressed. If you do decide to separate the SVGs out into external SVG files, then you'll want to check that the HTTP requests to those SVG files are also served with HTTP/2 and either gzip or brotli. Commented Sep 20, 2021 at 20:45
  • 5
    compress-or-die.com/svg <--- I use a lot. Christoph also has a nice api - compress-or-die.com/developers Commented Sep 20, 2021 at 20:57
  • 2
    @SyedMohammadSannan As far as images go, most image formats such as png and jpg come already-compressed, so it's fine and even desirable that your server doesn't try to recompress those with gzip. SVG is an exception though because it is an uncompressed image format due to being text-based. If your server is not applying gzip to your externally linked .svg files, you will want to configure it to do that before you consider making the rest of the SVGs external, if that's the path you choose to go. Commented Sep 20, 2021 at 21:54
  • 9
    @SyedMohammadSannan "It's a single-page-web-app, It has different popups based on the buttons you click" - Just because it's a SPA doesn't necessarily mean everything needs to be downloaded from the get go (although this may be difficult to refactor after the fact). External SVGs can also take advantage of persistent caching that inline images cannot.
    – MrWhite
    Commented Sep 21, 2021 at 10:19
24

I don't think using separate SVG files for the images would be any better because that would take even more time to load because of separate HTTP requests.

Efficient handling of linked images is something that browsers are specifically designed to do well. By inlining 23 MB of data in the HTML, you're blocking those optimizations.

If you split the icons to individual files, then the browser will cache individual icons and avoid redownloading them when the same icon is used repeatedly, on the same page load and on separate page loads. The browser will also be able to display the full text of the page before receiving all the images, which will improve the user experience.

Also, your SVGs are overcomplex for rendering at typical icon size. 23 MB for 140 images is an average of 168 kB per image. How big are they displayed? A small icon, 32×32, at 3 bytes per pixel is 3 kB even as a completely uncompressed raw bitmap. A larger icon, 128×128, at 3 bytes per pixel, is a 48 kB raw bitmap. And uncompressed is the most pessimistic scenario to compare against. The point is, your SVGs contain more detail than you can possibly see at icon size. If you prerender them to PNGs, it will look identical but be dramatically smaller and lighter.

If you have the option to change the icons, you could also experiment with a different icon style. The current vogue is a flat iconographic shape with one or two colors, which happens to compress much smaller than a glossy gradient skeuomorphic icon. Changing the entire icon style is probably not necessary to fix your current performance problem, but if you needed to support very slow connections, it would help.

1
  • 1
    Thanks a lot for the answer, It's all clear now. I even managed to reduce the loading time to 40 seconds by far :D because of you guys' answers Commented Sep 21, 2021 at 17:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.