Cookies setzen und auslesen mit JS und Smarty

Wie gestern bereits angemerkt sollte die Einbindung von Font Face Observer noch weiter verbessert werden, indem man nach dem erstmaligen laden von Webfonts – wenn sie also normalerweise im Browsercache liegen sollten – ein Cookie setzt und die Ausführung von Font Face Observer von diesem Cookie abhängig macht, damit wiederkehrende Besucher nicht auf jeder Seite einen unnötigen FOUT sehen.

Cookie setzen in Javascript

Ich bin nicht der große JS-Experte, daher verwende ich gern das cookie-Utility der Filament Group. Damit reduziert sich das setzen und prüfen von Cookies in JS auf ein paar sehr simple Zeilen:

if(!cookie('webfonts')) {
    // Generate a font face observer
    var font = new FontFaceObserver('calendas_plus');

    font.load(null, 5000).then(function () {
        // Add webfonts class to html element
        document.documentElement.className += " fonts-loaded";
        // Set webfonts cookie
        cookie('webfonts', '1', 7);
    });
}

Man prüft also, ob das Cookie (nicht) gesetzt ist (was normalerweise für einen erstmaligen Besuch spricht) und führt dann den bereits bekannten Code für Font Face Observer aus – mit dem Unterschied, dass nun abschließend das Cookie gesetzt wird. Der Wert des Cookie ist für unsere Zwecke egal; es gilt für sieben Tage.

Cookie auslesen in Smarty

Das bedeutet aber auch, dass für wiederkehrende Besucher die Klasse fonts-loaded, über die wir den Webfont setzen, nicht mehr per JS gesetzt wird. Wir wollen sie statt dessen im (hier im Blog per Smarty) dynamisch erzeugten Markup setzen, was bereits geschieht, ehe JS auch nur ausgeführt wird. In Smarty geht das z.B. so:

<html class="no-js{if $smarty.cookies.webfonts != ''} fonts-loaded{/if}" lang="{$lang}">

(Somit ist übrigens nebenbei auch sicher gestellt, dass der Webfont bei deaktiviertem JS geladen wird, was bei reinem laden über Font Face Observer nicht der Fall gewesen wäre, da die nötige Klasse nie gesetzt würde.)

Die perfekte Lösung?

Jein. Die Methode basiert auf der Annahme, dass der Besucher das Setzen von Cookie zulässt und den Browsercache nutzt. Natürlich kann es Benutzer geben, die eines oder beides nicht tun – ich fürchte, die müssen dann hier damit leben, dass sie einen FOUT und/oder schlechtere Performance bekommen.

Zudem hängen natürlich Browsercache und Cookie-Speicher nicht voneinander ab, es ist also durchaus denkbar, dass das Cookie zwar gesetzt ist, der Webfont aber nicht im Browsercache liegt oder umgekehrt. In dem Fall entsteht dann leider eben doch das unerwünschte Blockieren des Seitenrenderings.

Außerdem ist diese Methode natürlich überhaupt nur anwendbar, wenn Möglichkeiten vorhanden sind, das Markup serverseitig dynamisch zu generieren – rein in statischem HTML kann man nun mal Markup nicht abhängig von Bedingungen erzeugen.