If you’ve ever worked in a project architected as a single-page application, the following pattern may look familiar:
<!doctype html> <title>My Application</title> <div id="app"></div> <script src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> <script> ReactDOM.render( React.createElement( 'span', null, 'Hello World' ), document.getElementById( 'app' ) ); </script>
Note the empty div
element. While this example uses React, most any of the common JavaScript frameworks will follow this convention of mounting an application into some root container element. It’s not until the application code has loaded and computed the rendered result that anything is shown on the page.
If an application uses custom fonts, there’s an interesting side-effect of this loading procedure which we might not anticipate. Presumably in an effort to optimize network requests of unused assets, Chrome will not load a font file if there is not any text in the page which uses that font. Even if we declare the fonts used in a CSS @font-face
rule, a font file will not be requested until after the initial rendering of the application. This is due to the fact that, until that point, there’s effectively no text shown anywhere in the page.
This has the unfortunate effect of introducing what is known as a “flash of unstyled text”, where the text in an application may be shown using a fallback font until the font has finished loading.
Ideally, if we know that our application will render text, we would want the font to be loaded as early in the page lifecycle as possible.
Continue reading