From 1214e6dd294e217fba540796d79f73db48c68c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Fri, 21 May 2021 22:02:27 +0200 Subject: [PATCH] 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 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). --- app/assets/stylesheets/mixins/icons.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/mixins/icons.scss b/app/assets/stylesheets/mixins/icons.scss index 4eb1b09e0..b5d2a93c1 100644 --- a/app/assets/stylesheets/mixins/icons.scss +++ b/app/assets/stylesheets/mixins/icons.scss @@ -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}); } }