Hi, i've optimizing websites for better PageSpeed Insights, and by a while I mean a few months.
The process of speeding up sites is usually quite similar in most cases, with over sized images being the most common offender, but there is always so much that can be done to speed up a site. So I've a tick or two to share.
1.Utilizing google fonts API options to optimize your fonts.
Google offers a great resource for using Webfonts, the Google Fonts API.
Webfonts are great, they're also pretty heavy, and can usually be optimized quite a bit in most cases I've seen.
The first optimization is to reduce the number of HTTP requests by concatenating the font requests to one URL.
For example:
Instead of the following
ttps://fonts.googleapis.com/css?family=Inconsolata
https://fonts.googleapis.com/css?family=Tangerine
Can be concatenated as
https://fonts.googleapis.com/css?family=Inconsolata|Tangerine
You could also reduce the request depth by going to https://fonts.googleapis.com/css?family=Inconsolata|Tangerine direcrtly and extracting the @font-family declarations there into your stylesheet, like this:
/* vietnamese */
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata Regular'), local('Inconsolata-Regular'), url(https://fonts.gstatic.com/s/inconsolata/v18/QldKNThLqRwH-OJ1UHjlKGlW5qhWxg.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata Regular'), local('Inconsolata-Regular'), url(https://fonts.gstatic.com/s/inconsolata/v18/QldKNThLqRwH-OJ1UHjlKGlX5qhWxg.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata Regular'), local('Inconsolata-Regular'), url(https://fonts.gstatic.com/s/inconsolata/v18/QldKNThLqRwH-OJ1UHjlKGlZ5qg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Tangerine';
font-style: normal;
font-weight: 400;
src: local('Tangerine Regular'), local('Tangerine-Regular'), url(https://fonts.gstatic.com/s/tangerine/v11/IurY6Y5j_oScZZow4VOxCZZM.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
of course this is dangerous if google's API automatically changes the source fonts, which is totally possible over time.
Another very unused feature of the API is to remove unused letters from your font.
You can do this as by adding text= to your URL, like so:
https://fonts.googleapis.com/css?family=Inconsolata&text=Best%Discount%mattress
This will generate fonts that only have the letters that you put in the URL. This is great if your only using a font for a few headers, the above example generates a woff2 that weighs only 4.2kb!
Compare that to the 40ish kilobytes worth of files generated from
https://fonts.googleapis.com/css?family=Inconsolata
and here is a little piece of code to extract only the used text for a specific font.
let targetFontFamily = "Lustria";
function getFontFamily(element) {
return window.getComputedStyle(element, null).getPropertyValue("font-family");
}
let foundCharacters = new Set();
function walkTree(node) {
let fontFamilyMatch = getFontFamily(node).includes(targetFontFamily);
for (let child of node.childNodes) {
if (child.nodeType == Node.TEXT_NODE && fontFamilyMatch) {
let nodeText = child.textContent;
for (let i = 0; i < nodeText.length; ++i) {
foundCharacters.add(nodeText[i]);
}
} else if (child.nodeType == Node.ELEMENT_NODE) {
walkTree(child);
}
}
}
let chars = Array.from(foundCharacters)
.sort()
.join("")
.replace(/[^a-z]/g, "");
walkTree(document.body);
console.log(chars);
Obviously, be sure to remove the character restriction if your going to be adding more written content.
Now you don't have to only google fonts to remove unused letters from fonts, its just the easiest implementation, but you can use font editing tools like Fontforge to remove Unused letters from a font file.
2. Inlining FontAwesome fonts as SVGs.
FontAwesome is awesome, I say this encase their name isn't self explanatory.
its one of the most used font libraries on the web, because everybody loves free icons.
It it does however come with a lot of bloat if you aren't using are the fonts in their library.
The most common way to use font awesome is to load their stylesheet through a CDN, as its super easy, like this:
https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css
Then just drop in a tag in your html with a font awesome class and you got a Nifty icon.
<i class="fas fa-smile-wink"></i>
However, the above font awesome css file comes in around 34kb, which is a lot if you're only one a single icon on your site.
You can reduce this by using a library to remove unused CSS, like purgeCSS, unCSS, or pruifyCSS.
Another way to reduce this even more to insert the font directly into your html as a SVG.
Every font on font on FontAwesome is also available as a SVG for downloaded.
The most simple way to implement them to simple up the SVG in your text editor and copy that text into your your html:
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="smile-wink" class="svg-inline--fa fa-smile-wink fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M0 256c0 137 111 248 248 248s248-111 248-248S385 8 248 8 0 119 0 256zm200-48c0 17.7-14.3 32-32 32s-32-14.3-32-32 14.3-32 32-32 32 14.3 32 32zm158.5 16.5c-14.8-13.2-46.2-13.2-61 0L288 233c-8.3 7.4-21.6.4-19.8-10.8 4-25.2 34.2-42.1 59.9-42.1S384 197 388 222.2c1.7 11.1-11.4 18.3-19.8 10.8l-9.7-8.5zM157.8 325.8C180.2 352.7 213 368 248 368s67.8-15.4 90.2-42.2c13.6-16.2 38.1 4.2 24.6 20.5C334.3 380.4 292.5 400 248 400s-86.3-19.6-114.8-53.8c-13.5-16.3 11.2-36.7 24.6-20.4z"></path></svg>
This you skips the extra HTTP request and request depth. Now on the flip side this increase the size of your html and add DOM depth, so it might depend whether using a optimized CSS fill is faster then inling an SVG.
If your only using a few icons(usually Facebook , Youtube and Instgram for social media links) I feel inline SVG will be a faster option.
So that's it, some of these improvements might only decrease your load time by a few milliseconds, but every millisecond counts when it comes to user experience and bounce rates.
Top comments (3)
I'd advise against doing things like extracting the font urls from Google's entrypoints. What if they change over time?
I have my doubts as to the benefits of font awesome at all in the face of writing coherent, accessible web documents.
Good point, I added that warning.
Out of curiosity, what is it about font awesome that makes a web document inaccessible?
I'm mostly thinking of the fact that you have to add extra markup and then hide it from screen readers. This means if you have something that's just an icon, you end up with two elements anyway. It's not that you can't fudge it to be accessible, it's that it makes extra hoops to jump through.
And if the font doesn't load properly, people get nonsense characters in their page.