Load SVG icons using asset-data-url

Back in commit 925f04e3f3 from pull request #4206 we wrote about our way
to load SVG icons:

> Using this technique will result in one HTTP request per icon, which
> might affect performance

We considered using CSS with Data URIs, and wrote:

> This method does not generate any extra HTTP requests and only
> downloads the icons we need. However, maintaining it is really hard,
> since we need to manually copy all the <svg> code for every icon we
> use, and do it again every time we upgrade Font Awesome.

Back when I wrote that, I didn't know Sass had a function named
`asset-data-url` which generated Data URIs automatically given a
filename. I searched for it, but somehow I only found Compass helpers
doing a similar thing.

Note we're using CSS variables to reduce the size of the generated CSS.
If we used `mask-image: asset-data-url(...)`, the generated CSS would
include the value returned by `asset-data-url` twice: once for the
`mask-image` property and once for the `-webkit-image` property.

The percentage of browsers supporting `mask-image` and not supporting
CSS variables is really small (less than 1%), so in that regard things
remain more or less the same and unsupported browsers will render the
icons using the `font-family: "Font Awesome 5 Free` property.

After these changes, the size of the generated CSS increases from 475KB
to 533KB. If we didn't use CSS variables, the generated CSS would use
591KB.

We believe this is acceptable because the SVG icons we use are very
small files (about 1-1.5KB big) and, downloaded separately, they also
amount to about 45KB, which is similar to the CSS file increase we get.
Using `asset-data-url` we download them in one request instead of having
one request per file (about 35 extra requests).
This commit is contained in:
Javi Martín
2021-05-21 22:02:27 +02:00
parent 9f0858ac40
commit 1214e6dd29

View File

@@ -5,7 +5,7 @@
}
%svg-icon {
@supports (mask-image: url()) {
@supports (mask-image: url()) and (--custom-property-name: custom-property-value) {
background: currentcolor;
content: "" !important;
height: 1em;
@@ -1502,6 +1502,7 @@ $font-awesome-icons: (
&::#{$position} {
@extend %svg-icon;
mask-image: image-url("fontawesome/#{$style}/#{$icon}.svg");
#{"--fa-icon-#{$style}-#{$icon}"}: asset-data-url("fontawesome/#{$style}/#{$icon}.svg");
mask-image: var(--fa-icon-#{$style}-#{$icon});
}
}