Modernizr: Load
Wie im Grundlagen-Artikel bereits angedeutet halte ich den integrierten Script-Loader mittlerweile für die wichtigere Komponente in Modernizr. Bevor wir uns den Loader genauer ansehen nochmals der Hinweis: Er wird nur in generierte Versionen eingebunden, die Entwicklerversion (die z.B. auch im HTML5 Boilerplate enthalten ist) kommt ohne Loader daher.
Warum überhaupt ein Script Loader?
Zunächst mal ist Modernizr.load
eigentlich kein Script-, sondern vielmehr ein Ressource-Loader – es kann nicht nur Javascript-, sondern auch CSS-Dateien nachladen, und das asynchron und parallel, wobei sie dennoch in der beabsichtigten Reihenfolge ausgeführt werden. Auch ist Modernizr natürlich bei weitem nicht der einzige Script-Loader – sein großer Vorteil ist die Integration mit Modernizr.
Performance
In Sachen Performance kann es vorteilhaft sein, mehrere kleine Skripte anstatt einer kombinierten Skript-Datei parallel zu laden, obwohl mehrere Skripte logischerweise auch mehrere HTTP-Requests bedeuten – muss es aber nicht. Der eigentliche Vorteil eines Script-Loaders in Zusammenhang mit Polyfills ist, dass man nur die Skripte (nach)lädt, die tatsächlich vom Browser benötigt werden, um Funktionalitäten nachzurüsten, die er nicht nativ beherrscht. Das spart in modernen Browsern in jedem Fall zu übertragende Daten ein. Im Übrigen ist es natürlich auch möglich, über den Loader zusammengefasste Skripte (etwa in Form einer oldie.js
) nachzuladen.
Die grundsätzliche Form
Allgemein sieht die Form eines Aufrufes von Modernizr.load
so aus:
Modernizr.load([
{
test: Modernizr.test,
yep: Aktion_1,
nope: [Aktion_2, Aktion_3],
},
]);
Wir testen also eine (oder mehrere über Javascript-Operatoren verknüpfte) Bedingung und führen in Abhängigkeit des Ergebnisses entweder die eine oder andere Aktion aus, wobei es nicht notwendig (und wohl auch in den wenigsten Anwendungsfällen sinnvoll) ist, beiden Testergebnissen eine Aktion, aber sehr wohl möglich, einem Ergebnis mehrere Aktionen (also etwa das Laden einer JS- und einer CSS-Datei) zuzuweisen. Wichtig ist allerdings die Reihenfolge, in der ggf. mehrere solcher Anweisungen in der Skriptdatei stehen, denn sie bestimmt auch die Reihenfolge, in der Ressourcen von Modernizr.load nachgeladen werden.
Testen kann man grundsätzlich alles, was Modernizr erkennt, nachladen kann man JS- und/oder CSS-Dateien. Ausführlichere Dokumentation zum Loader findet man auf der Webseite von yepnope, dem „Mutterprojekt“ von Modernizr.load
.
Ein praktisches Beispiel
Nehmen wir an, wir wollen für ein Projekt den placeholder-Polyfill von Dirk Ginader verwenden. Nachzuladen wären in Browsern, die placeholder
nicht nativ unterstützen, eine JS- und eine CSS-Datei, die Testbedingung ist auch klar:
Modernizr.load([
{
test: Modernizr.input.placeholder,
nope: [
"placeholder_polyfill.min.css",
"placeholder_polyfill.jquery.min.combo.js",
],
},
]);
Oder in Klartext formuliert: „Falls der Browser das input
-Attribut placeholder
nicht unterstützt, lade die CSS- und die JS-Datei nach“ (der Pfad zu den nachzuladenden Ressourcen ist hier relativ zum Dokument, das den Modernizr-Aufruf enthält). Wichtig auch hier: Die Tests basieren auf den tatsächlich vom Browser unterstützten Funktionen, nicht auf dem von ihm (eventuell fälschlich) übermittelten User Agent.
In jedem Fall lohnt sich ein Blick in die Dokumentation der Tests von Modernizr. Zum einen sind diese (zum Teil) nicht hundertprozentig verlässlich – so liefern zum Beispiel Palm Pre/WebOS-Geräte bei Modernizr.touch
ein false zurück, da diese Geräte trotz Touchscreen keine Touch-Events unterstützen. Des weiteren reicht es bei einigen Tests nicht, nur auf true/false zu prüfen – dem Test auf Media-Queries etwa sollte man einen Typ und muss man einen Wert mitgeben, also z.B. Modernizr.mq('only screen and (max-width: 768px)')
.
Selbstverständlich gilt auch hier, dass man sich in jedem Fall einen angepassten build von Modernizr erzeugen lassen sollte, der nur die Tests enthält, die man konkret benutzt, um Performance-Einbußen durch die Einbindung von Modernizr möglichst gering zu halten.
Nachtrag: Schepp hat mich per Twitter auf einen sehr umfassenden Vergleich gängiger Script-Loader aufmerksam gemacht. Danke!