Load Web Fonts Asynchronously to Avoid Render-Blocking CSS
Oct 14, 2016
Render-blocking CSS resources, such as web fonts, can hinder the performance of your website for your users. This is important for several reasons. First, we want to minimize the initial page rendering time. And second, we want to get a good PageSpeed Insights score. 🙂
Your page has 2 blocking CSS resources. This causes a delay in rendering your page.
Have you ever seen the error above in the PageSpeed Insights tool as a result of loading web fonts? In this brief tutorial I am going to show you how to load your web fonts asynchronously to avoid this issue. If you are not familiar with CSS and web fonts, check out our CSS3 for Web Designers and Developers course where we cover CSS3 topics, including web fonts.
Avoid @import
The first mistake I made was using @import
to load the web fonts:
/* Import Google Open Sans Font */
/*@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,500italic,600italic,700italic,400,500,600,700);*/
/*Import Google Roboto Font */
@import url(https://fonts.googleapis.com/css?family=);
This causes the browser to fetch the resource prior to the rendering of the page. This is because the browser is programmed to fetch and parse all CSS resources that are defined using @import
or the <link rel="stylesheet">
tag. To avoid this, we can load our web fonts asynchronously. While that might sound difficult, it’s not, thanks to TypeKit’s Web Font Loader open-source project.
Web Font Loader
A big thank you to the TypeKit team that has provided the Web Font Loader project. I am going to use Google’s Font API in my examples. If you are loading fonts from another source, such as TypeKit or FontDeck, check out the documentation for Web Font Loader on GitHub.
In this tutorial I am going to use the Node Package Manager (npm), which is part of Node.js. If you have not already installed Node.js then follow one of Webucator’s how-to articles:
If you want to learn more about Node.js and npm, check out our Node.js Software Development Training course. It’s a 2-day course where you learn the basics of Node.js, using npm for dependency management, accessing the file system, and even running an HTTP server using Express.
Ok, let’s install the Web Font Loader library using npm:
$ npm install webfontloader --save
Notice that I am using the --save
flag so that the webfontloader
dependency will be saved into my project’s package.json file.
Webpack
Next, I am going to use Webpack to load the webfontloader.js file into a vendor bundle. I like to separate out the JavaScript (JS) for a project into two bundles: a vendor bundle and an application bundle. The vendor bundle contains all of the JS libraries that I am using. These do not change much, so I can let this file be cached in the browser. The application bundle contains all of the JS code for my application, which changes frequently with each release. I then use cache busting strategies on my application bundle file when pushing a release.
Here is what my webpack.config.js file looks like:
var path = require("path");
var webpack = require("webpack");
module.exports = {
"devtool": "source-map",
"entry": {
//main entry
"main": path.resolve(__dirname, "./js/src/main.ts"),
//third-party libraries
"vendor": [
//others ommitted
"webfontloader"
]
},
"output": {
"path": "./js/build",
"filename": "[name].bundle.js"
},
"resolve": {
"alias": {
//webfontloader (https://github.com/typekit/webfontloader)
"webfontloader": path.resolve(__dirname, "./node_modules/webfontloader/webfontloader.js")
},
"extensions": ["", ".webpack.js", ".web.js", ".js", ".ts"],
"modulesDirectories": ["node_modules", "bower_components"]
}
};
Some things to note:
- Within the
enty.vendor
array I have included thewebfontloader
dependency. - I defined the
webfontloader
alias within theresolve.alias
object.
Install TypeScript Declarations
In this tutorial I am going to use TypeScript. You can ignore the typings in my code examples and skip this step on installing the TypeScript definitions if you are using vanilla JS.
If you do not have typings installed, let’s do that first:
$ npm install typings --global
I installed typings globally so that I can use it in other projects as well. You can choose to not do this, and then access the binary in ./node_modules/.bin/. Once we have typings installed, let’s install the webfontloader
TypeScript declaration files:
$ typings install dt~webfontloader --global --save
Let’s break down this command, as it is a bit long and potentially confusing. The typings install
portion is pretty simple; we’re telling the typings command to run the install command. Then we provide the location. We are instructing typings to use the source dt
and the package webfontloader
. The source of dt
stands for DefinitelyTyped, which is a publicly available repository of TypeScript declaration files. The source of the webfontloader
declaration file can be found on GitHub in the DefinitelyTyped repository. Finally, we specify the --global
and --save
flags. The --global
flag instructs typings to install and persist the declaration file as a global definition. And the --save
flag instructs typings to save the dependency to the typings.json file.
Load Fonts via WebFont
We are now ready to require the WebFont
module into our TypeScript code and to load our web fonts asynchronously using Web Font Loader. First, we need to require()
the WebFont
module:
//require webfontloader
var WebFont = require("webfontloader");
Next, create a configuration object for WebFont
. This is where you will use your own configuration based on the web fonts in your application or on your website. I am going to use Google’s Open Sans and Roboto fonts.
let config: WebFont.Config = {
google: {
families: [
"Open Sans:400italic,500italic,600italic,700italic,400,500,600,700",
"Roboto:400,900,100"
]
}
};
Finally, using the config
object, load the fonts using the load()
static method on WebFont
:
WebFont.load(config);
To verify everything is working, check Chrome’s Network tab in the Development Tools and you should see that the fonts are now being loaded using webfontloader.js:
Webucator provides instructor-led training to students throughout the US and Canada. We have trained over 90,000 students from over 16,000 organizations on technologies such as Microsoft ASP.NET, Microsoft Office, Azure, Windows, Java, Adobe, Python, SQL, JavaScript, Angular and much more. Check out our complete course catalog.