Reducing website size by a half by optimising Bootstrap and FontAwesome

My new blog, despite being simple and freshly rewritten, loads way too much crap... So I took a few moments to optimise it a bit – and I ended up with almost 50% reduction in resources size in just two steps!

Bootstrap

Bootstrap is awesome. But it’s also a lot. Modals? Popovers? Tooltips? Badges? Toasts? I don’t use any of that!

I already don’t include any of Bootstrap’s JavaScripts, but I should definitely clean up its CSS.

So instead of including

@import "~bootstrap"

I went to its source and copy-pasted the modules that it was loading over there, commenting out the ones I don’t need:

@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
@import "~bootstrap/scss/root";
@import "~bootstrap/scss/reboot";
@import "~bootstrap/scss/type";
//@import "~bootstrap/scss/images";
@import "~bootstrap/scss/code";
@import "~bootstrap/scss/grid";
@import "~bootstrap/scss/tables";
//@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/buttons";
//@import "~bootstrap/scss/transitions";
//@import "~bootstrap/scss/dropdown";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/input-group";
//@import "~bootstrap/scss/custom-forms";
//@import "~bootstrap/scss/nav";
//@import "~bootstrap/scss/navbar";
@import "~bootstrap/scss/card";
//@import "~bootstrap/scss/breadcrumb";
//@import "~bootstrap/scss/pagination";
//@import "~bootstrap/scss/badge";
//@import "~bootstrap/scss/jumbotron";
@import "~bootstrap/scss/alert";
//@import "~bootstrap/scss/progress";
//@import "~bootstrap/scss/media";
//@import "~bootstrap/scss/list-group";
//@import "~bootstrap/scss/close";
//@import "~bootstrap/scss/toasts";
//@import "~bootstrap/scss/modal";
//@import "~bootstrap/scss/tooltip";
//@import "~bootstrap/scss/popover";
//@import "~bootstrap/scss/carousel";
//@import "~bootstrap/scss/spinners";
@import "~bootstrap/scss/utilities";
@import "~bootstrap/scss/print";

The only issue is that I do use forms.scss a bit. There is a search form in the header that has its <input> field styled.

So I just inspected that element in Opera and pretty much just copy-pasted the three relevant selectors.

Bum! Starting off with a minified CSS file of 244 KB, now it’s down to 184 KB. A third of its weight is now gone.

But that’s just the first step.

FontAwesome

The real big deal in terms of the website weight were the FontAwesome icons. There’s thousands of icons included, but I only use a dozen – so why do I make visitors download them all?

You can load FontAwesome in a number of different ways. One of them are SVG sprites. You can include the definitions of the icons in a form of SVG <symbols>s, and whenever they’re used, just use a <use> tag to reference it.

So a wrote a simple service (plus a Twig extension) that would do exactly that:

  • put <use> tags wherever an icon should be displayed,
  • keep track of the icons used,
  • dump the definions of the used icons at the bottom of the page.

I just had to add some CSS to display the SVG icons the same way as webfonts in terms of size, position and using the color of the surrounding text:

.icon {
    width: 1.1em;
    height: 1.1em;
    vertical-align: -.125em;
    fill: currentColor;
}

Et voilà! The homepage of my blog went down from 765 KB at the beginning, to 704 KB after the first step, to 393 KB now!

Btw, I’ve put my little helper into a library, if you want to check it out.

There’s caveats though... SVG is heavy. The two .woff2 files I was using are 261 KB overall, while the corresponding two sprites are 2.1 MB. But if I filter their content to just the icons I actually use (which is way simpler to do in SVG than in webfonts), it goes down to just 44 KB! So if your website is using a looot of fonts, you’ll probably be better of generating a custom webfont.

There can also be issues related to warm caches possibly circumventing the Optimiser, with data that includes new icons being loaded dynamically in JS (which I don’t do), with the increased execution time (which doesn’t bother me since I use an HTTP cache), etc. Still, in many cases this trick can be very useful. Like mine.

Switching from webfonts to dynamically filtered SVG sprites not only removed the need for two requests .woff2 files, but also the need for the CSS that maps class names to font glyphs. My CSS file went down again, from 184 KB to just 96 KB.

Summing up

So here I am: having spent not even a full evening on it, doing optimisations as simple as they can get, and ending up with the website trimmed of half of its fat.

Nice 😎