Removing FontAwesome

Next target of optimizing on my Hugo site is to minify or remove FontAwesome. After a bit of investigating I decided to just remove it all and handle the SVGs that I will be using myself.

Which would cross another thing off my original list

  • Removing unused CSS
  • Minifying/Removing FontAwesome
  • Minimizing requests to 3rd parties (fonts, metrics, etc)
  • Remove Google Fonts while still looking appealing
  • Minimizing use of JavaScript
  • Converting Images to WebP or some other optimized formats

Remove FontAwesome

I removed any mention of the FontAwesome font and/or stylesheet. Normally it’s something like

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/XXX/css/font-awesome.min.css">

The theme I was using also had a local version called ForkAwesome installed. Just needed to remove the files from the static folder and remove the links to it.

<link rel="preload" href="/fonts/forkawesome-webfont.woff2?v=1.1.7" as="font" type="font/woff2" crossorigin>

Don’t remove any of the class tags just yet (fa, fa-XXXX, etc).

Fetch the Needed SVGs

Next I wrote a script that will

  • Go through my html, js and config.toml files looking for fa-.
  • Check which SVGs are missing
  • Download the SVG from the FontAwesome GitHub Repo into the ./fontawesome folder
#!/usr/bin/env bash
regex='.*fa-([^2].*)("|\s|$).*'
fa=()

var=`grep -rh --include \*.html --include \*.js './themes/' -e 'fa-'`
for f in $var
do 
    if [[ $f =~ $regex ]]
    then
        fa+=( "${BASH_REMATCH[1]}" )
    fi
done

var=`grep -h './config.toml' -e 'fa-'`
for f in $var
do 
    if [[ $f =~ $regex ]]
    then
        fa+=( "${BASH_REMATCH[1]}" )
    fi
done

uniq=($(printf "%s\n" "${fa[@]}" | sort -u)); 

dest=fontawesome
ghurl=https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs
folders=( brands solid regular )

mkdir -p "${dest}"
for icon in "${uniq[@]}"
do 
    icon="${icon%\"}.svg"
    if [ ! -f "${dest}/fa-${icon}" ]; 
    then
        echo "${icon}"
        for folder in "${folders[@]}"
        do 
            url="${ghurl}/${folder}/${icon}"
            if ! curl -s --head --request GET ${url} | grep "404" > /dev/null
            then
                curl -o "${dest}/fa-${icon}" ${url}
                break
            fi
        done
    fi
done

The SVGs are in 3 different folders on the repo, brands, solid and regular. Currently I just check each folder in that order, but eventually I may add logic to support determining if the SVG would be in solid or regular depending on the -o tag.

If you add a new fa- icon to your site, be sure to run the script before starting the Hugo server/build or else it will yell at you. I’m hoping they add a way to add pre-build events so I can hook into that, but the adding of icons isn’t a common occurrence for me so not a big issue.

Create the Partial

Next is to create a partial in hugo to inject the SVG.

I construct the icon path, read the file and inject fill=\"currentColor\" into the path so that I can change it’s color.

//fa.html
<i class="fa inline-svg" aria-hidden="true">
    {{- $fname:=print "fontawesome/" . ".svg" -}}
    {{- replace (readFile $fname) "<path" "<path fill=\"currentColor\"" | safeHTML -}}
</i>

I’m not 100% sold on using an i element for them, but will leave it that for now.

With that set, I went around the system replacing the old code with the new partial.

Old:

 <i class="fa fa-link" aria-hidden="true"></i>

New:

 {{ partial "fa.html" "fa-link" }}

And that was pretty much it.

Tweaks

There was a few tweaks that I needed to make due to sizing and positioning.

First was to remove all the sizing tags (fa-2x, etc) and handled them myself. Best way I found was setting the font-size.

.inline-svg {
    font-size: XXX;
}

I also added this to my css to help with alignment to text

.inline-svg {
  display: inline-flex;
  align-self: center;
}
.inline-svg svg {
  font-size: inherit;
  height: 1em;
  width: 1em;
  top: .125em;
  position: relative;
} 

But after that it’s been smooth sailing. Was really surprised at how easy it was and it’s another 3rd-party dependency gone without a loss in functionality!