Loading webfonts

Iedere milliseconde telt bij het optimaliseren van je website, en de manier waarop lettertypen geladen worden heeft een grote invloed op de gebruikerservaring. In dit artikel ontdek je hoe je fontweergave kunt verbeteren zonder dat bezoekers afhaken.

FOIT, FOUT, Font Face Observer en Font-display 

De wereld van webdevelopment staat nooit stil en is continu in ontwikkeling. Dit uit zich in nieuwe denkwijzen zoals de BEM-methodologie, ITCSS-bestandsstructuur en nieuwe programmeertalen en frameworks zoals React en TypeScript. Soms betreft het ook kleine toevoegingen binnen een bestaande taal. Op het eerste gezicht lijken deze specificaties misschien niet belangrijk. Toch hebben ze een grote impact op de toekomst van het web. In dit artikel ga ik dieper in op een van deze recent toegevoegde specificaties aan CSS: font-display. Daarnaast leg ik uit wat dit voor invloed heeft op het laden en tonen van webfonts.

Webfonts 

Webfonts zijn tegenwoordig niet meer weg te denken uit webontwikkeling. Het is een middel geworden om een website of webapplicatie te onderscheiden, de identiteit van een merk beter uit te dragen en het geheel visueel aantrekkelijker te maken. Waar we vroeger alleen systeemfonts konden gebruiken (zoals Arial, Georgia en Verdana), hebben we nu de mogelijkheid om elk gewenst font toe te passen. 

Er zit ook een keerzijde aan webfonts: in vergelijking met systeemfonts moet het font eerst gedownload worden. Dit neemt tijd in beslag en kan ook fout gaan (bijvoorbeeld als een externe dienst offline is), waardoor het font niet binnengehaald kan worden. Vaak gaat men er echter vanuit dat het font gewoon beschikbaar is en wordt het in de styling veel toegepast. 

Maar hoe voorziet een browser een stuk tekst van een lettertype dat nog niet beschikbaar is? Hedendaagse browsers passen hiervoor momenteel een van de twee volgende implementaties toe: Flash of Invisible Text (FOIT) of Flash of Unstyled Text (FOUT). 

Flash of Invisible Text (FOIT) 

Flash of Invisible Text is de meestgebruikte implementatie en wordt toegepast door alle browsers, met uitzondering van Internet Explorer en Edge (tot en met versie 18). Het komt erop neer dat tekst met een webfont niet zichtbaar is tot het font gedownload is, of tot er een bepaalde tijd is verlopen. Deze duur verschilt per browser en kan variëren van drie tot dertig seconden.

Flash of Invisible Text

Denk eens terug aan een door jou recent bezochte website, terwijl je op een trager netwerk zat. Komt het je bekend voor dat de site wel voorzien was van de overige vormgeving, maar er nog geen tekst werd weergegeven? De reden hiervoor is de FOIT-implementatie voor het laden van de fonts. Nu denk je misschien: wat maken die paar seconden uit? Die paar seconden spelen een grote rol in conversieverlies en een hoger bouncepercentage. 

Hoe langer het duurt voordat de tekst verschijnt, hoe groter de kans dat mensen afhaken en de informatie elders gaan zoeken. Uit onderzoek door Akamai, een leidende partij in veilig en snel internet, blijkt dat de helft van webgebruikers verwacht dat een website sneller laadt dan twee seconden. En dat het merendeel van deze mensen de website zou verlaten als het langer duurt dan drie seconden om te laden. Het is daarom belangrijk om de pagina zo snel mogelijk te laden of om in ieder geval het gevoel te geven dat de pagina snel laadt. Als door de FOIT de tekst al drie seconden lang niet toont, zullen enkele bezoekers al afhaken. 

Flash of Unstyled Text (FOUT) 

De tweede implementatie Flash of Unstyled Text houdt in dat een fallback font wordt gebruikt, dat met het juiste webfont wordt omgewisseld zodra deze klaar is. Met deze implementatie is de tekst eerder leesbaar, dus eerder bruikbaar en voelt het bovendien gevoelsmatig 'sneller geladen' aan vergeleken met de FOIT-implementatie.

Flash Of Unstyled Text

Voorbeeld van een fallback font met optimalisaties om het meer op het juiste font te laten lijken:

Flash of Unstyled Text Optimized

Beide implementaties zijn niet ideaal, omdat bij beide een ongewenste verspringing van de content plaatsvindt: van niets naar het juiste font (FOIT) of van het afwijkende fallback font naar het juiste font (FOUT). Kortom, het is kiezen voor het minste kwaad en dat is op dit moment de Flash of Unstyled Text-implementatie. Microsoft heeft met hun browsers de juiste implementatie gekozen; alhoewel Edge sinds het overstappen op de Chromium engine nu ook de FOIT toepast. 

Aangezien er de afgelopen tijd steeds meer aandacht is gekomen voor het laden van webfonts, is men naar manieren gaan zoeken om in alle browsers de FOUT-implementatie te kunnen afdwingen. Dit heeft geresulteerd in bijvoorbeeld de Javascript-oplossing Font Face Observer en de CSS-oplossing font-display. Tot nu toe was de Font Face Observer de manier om dit voor elkaar te krijgen, aangezien het gegarandeerd in alle browsers werkt. Maar door de steeds betere ondersteuning door browsers kan de font-display specificatie deze rol ondertussen overnemen - afhankelijk van welke browsers de website moet ondersteunen. 

Font Face Observer 

Wil je er zeker van zijn dat alle mogelijke browsers en versies voorzien worden van het gewenste laadgedrag, dan is het aan te raden om de Font Face Observer te gebruiken. Wat dit script doet is kijken of het font binnengehaald is en op basis daarvan een signaal afgeven. Door dit signaal af te vangen kan een vervolgactie worden uitgevoerd, zoals een class toevoegen op het HTML-element.

FFO javascript

Als fallback krijgt het body element het systeemfont Arial toegekend, met enkele stylewijzigingen om het verschil tussen de beide fonts zo klein mogelijk te maken. Zodra het font gedownload is, wordt de class apercu–loaded toegevoegd op het HTML-element. Dit zorgt er op zijn beurt voor dat het webfont toegepast wordt en dat de FOUT plaatsvindt.

FFO cascading style sheet

De hierboven beschreven standaardimplementatie betekent wel dat deze zelf toegepaste FOUT bij elk opvolgend paginabezoek wordt uitgevoerd, wat uiteraard niet gewenst is. Je kunt aannemen dat het font bij het eerste bezoek in de browsercache is opgeslagen en dus haast direct beschikbaar is. Om hiervan gebruik te maken en niet opnieuw de FOUT te forceren, plaatsen wij een (functionele) cookie die gedurende de sessie bewaard blijft. Als deze cookie aanwezig is, wordt het Javascript-deel overgeslagen en zetten we direct de classes op het HTML-element. Dit zorgt ervoor dat de Flash of Unstyled Text maar één keer plaatsvindt. 

Font-display 

Mocht je enkel ondersteuning bieden voor de grotere spelers op de browsermarkt of progressive enhancement toepassen, dan is het gebruik van font-display de betere oplossing. De laatste jaren hebben naast Chrome en Opera ook de andere veelgebruikte browsers zoals Firefox, Safari, Edge en diverse mobiele browsers ondersteuning toegevoegd voor de specificatie. Dit stelt ons in staat om met één extra regel CSS hetzelfde te realiseren waarvoor de Font Face Observer al snel zo'n tientallen tot honderden regels code nodig had. 

Het font-display attribuut wordt toegevoegd aan de @font-face declaratie. 

Font Display

De specificatie heeft een vijftal beschikbare waarden (auto|block|swap|fallback|optional), die allemaal andere tijdslimieten en ander gedrag tonen qua wisseling van de fonts. Zo wordt bij block|swap het font sowieso toegepast, hoe lang het downloaden ook duurt. Daarentegen kan er bij de optie fallback|optional na een bepaalde tijd besloten worden door de browser om het downloaden stop te zetten en de tekst in het fallback font te blijven tonen. In het artikel Controlling Font Performance with font-display op Google Developers lees je meer over de verschillen tussen de opties. 

Een belangrijke kanttekening: als je een externe bron gebruikt, zoals Adobe Fonts (het vroegere Typekit) of Google Fonts, in plaats van self-hosted fonts dan ben je afhankelijk van de ondersteuning die de desbetreffende partij aanbiedt. Het goede nieuws is dat de eerste stap gezet is door Google: zij hebben in mei 2019 ondersteuning toegevoegd aan Google Fonts. 

Kleine implementaties, grote impact 

In de constante strijd om de ervaring op het web te verbeteren en aan de verwachtingen van gebruikers te voldoen, zijn ogenschijnlijk kleine implementaties zoals hierboven beschreven zeer impactvol. Het kan de periode dat iemand zit te wachten op leesbare tekst namelijk drastisch inkorten, waardoor de gebruiker sneller geneigd is om op de website te blijven. Hierdoor neemt uiteindelijk de kans op conversie toe en neemt het bouncepercentage af: een betere ervaring voor de gebruiker, en betere resultaten voor de eigenaar van de website.