pixelgrade / customify

Intuitive Website Styling integrated into WordPress' Customizer
GNU General Public License v2.0
28 stars 5 forks source link

Explore giving up Web Font Loader script for the frontend #218

Closed vladolaru closed 4 years ago

vladolaru commented 4 years ago

Since browsers have gotten clever about loading fonts in the most efficient way (via @font-face declarations), it would be great if we could make use of this. It would mean big performance gains.

At the same time, it would make customizing fonts more flexible since we would not need to know what font variants need to be loaded beforehand. The problem is that right now we either load only the variant selected or all the variants available for a certain font. This is because the Web Font Loader script needs to be told explicitly what variants to load; it will load only those.

The only drawback of relying on browsers to load fonts is that we don't get the JavaScript events that Web Font Loader provides (e.g., wf-active). So we would need another way of determining when the browser has loaded all the font files (maybe based on the browser network).

vladolaru commented 4 years ago

Some initial resources and hints

Libraries

https://github.com/patrickmarabeas/jQuery-FontSpy.js Old library that tries to visually determine if the width of a certain text has changed.

https://github.com/smnh/FontLoader A somewhat newer library that also tries to determine when certain font families have been applied. It seems somewhat more robust.

https://github.com/bramstein/fontfaceobserver This is quite promising. 3-Clause BSD license ("New BSD License") that is compatible with GNU GPL, so no problems there.

Browser APIs

It seems that browsers are bridging the gap with https://developer.mozilla.org/en-US/docs/Web/API/CSS_Font_Loading_API and https://www.w3.org/TR/css-font-loading/#FontFaceSet-interface. The browser support seems pretty good especially when considering we only need the ready API (https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready or https://caniuse.com/#search=FontFaceSet)

There is even a simpler way to do it for document: https://developer.mozilla.org/en-US/docs/Web/API/Document/fonts (it uses the same APIs).

This is the browser list we are interested in supporting: https://browserl.ist/?q=%3E0.5%25+or+last+2+versions For other browsers, we simply trigger the wf-active event on window loaded, like we do now for system fonts.

We could also fall back on a library when the browser doesn't support the FontFaceSet interface.

Initial conclusions

With the wide browser support for FontFaceSet (around 80%) and a library like FontFaceObserver it seems very doable.

vladolaru commented 4 years ago

Ok. I have decided to go ahead with this as the upside is worth it: offer a more performant frontend for site visitors and save a ton of CO2 in not-loaded font files.

vladolaru commented 4 years ago

Well the exploration is over and I've decided to use only the FontFaceSet browser API on the frontend and, as a fallback, simply wait a little bit after the window loaded event to trigger the fonts active events.

vladolaru commented 4 years ago

Done!