Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically Load fonts

I need around 150 fonts for my project. Loading all the fonts initially increases the page load time.

I tried googling but could not find an answer.

Scenario:

User will select a font option from <select> tag. and upon click, I have to retrieve the font dynamically and make sure the font is rendered by the browser and then use the font to avoid a Flash of Unstyled Text (FOUT)

Currently I am using AJAX to request that font file

      $.ajax({
      type: 'GET',
        url: "font-file-url",
        async:false,
        success: function(data) {
            $("style").prepend("@font-face {\n" +
            "\tfont-family: \""+fontValue+"\";\n" + 
            "\tsrc: local('☺'), url("font-file-url") format('opentype');\n" + 
            "}");
         }
      });

Problem

I dont know when exactly the font is being rendered by the browser, so I end up displaying FOUT

like image 669
Abhinav Avatar asked Jan 25 '17 13:01

Abhinav


People also ask

What is the best way to load fonts?

The optimal way to load fontsPreconnect to the font file origin. Preload the font stylesheet asynchronously with low priority. Asynchronously load the font stylesheet and font file after the content has been rendered with JavaScript. Provide a fallback font for users with JavaScript turned off.

How do I load a font into JavaScript?

Now, to import a font, simply add a stylesheet or <style> element to the DOM, which has a font-face rule: var link = document. createElement('link'); link. setAttribute('rel', 'stylesheet'); link.

How do I know if a font is loaded?

check() The check() method of the FontFaceSet returns whether all fonts in the given font list have been loaded and are available.


2 Answers

You can use the native Font Loading API, a 3rd party package is no longer needed. Here is a working example:

document.getElementsByTagName('button')[0].onclick = async function() {

  const myFont = new FontFace('Pacifico', 'url(https://fonts.gstatic.com/s/pacifico/v21/FwZY7-Qmy14u9lezJ-6H6MmBp0u-.woff2)');
  await myFont.load();
  document.fonts.add(myFont);

  document.getElementsByTagName('h1')[0].style.fontFamily = "Pacifico";
}
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <h1>Hello world!</h1>
  <button>Dynamically load font</button>
</body>

</html>
like image 82
user9408899 Avatar answered Sep 19 '22 13:09

user9408899


You can now use the Font Loading API to detect when all fonts have been loaded. This should work in most modern browsers.

// Wait until all fonts are loaded:
document.fonts.ready.then(() => init());
like image 23
CrazyTim Avatar answered Sep 21 '22 13:09

CrazyTim