loadCSS: Die Funktion lässt dich CSS-Stylesheets asynchron nachladen
CSS nur bei Bedarf zu laden, kann mehrere nützliche Anwendungsfälle haben. Ein Beispiel wäre, dass ihr nur die CSS-Regeln beim Seitenaufruf ladet, die bei der Darstellung des sofort sichtbaren Bereichs benötigt werden. Und genau das ist mit loadCSS möglich: CSS dann nachzuladen, wenn ihr es braucht.
Um das zu bewerkstelligen, ist nur ein kleiner JavaScript-Schnipsel im Head erforderlich (hier nutzen wir der besseren Übersichtlichkeit halber nicht die minifizierte Version):
/*!
loadCSS: load a CSS file asynchronously.
[c]2014 @scottjehl, Filament Group, Inc.
Licensed MIT
*/
function loadCSS( href, before, media ){
"use strict";
// Arguments explained:
// `href` is the URL for your CSS file.
// `before` optionally defines the element we'll use as a reference for injecting our <link>
// By default, `before` uses the first <script> element in the page.
// However, since the order in which stylesheets are referenced matters, you might need a more specific location in your document.
// If so, pass a different reference element to the `before` argument and it'll insert before that instead
// note: `insertBefore` is used instead of `appendChild`, for safety re: http://www.paulirish.com/2011/surefire-dom-element-insertion/
var ss = window.document.createElement( "link" );
var ref = before || window.document.getElementsByTagName( "script" )[ 0 ];
ss.rel = "stylesheet";
ss.href = href;
// temporarily, set media to something non-matching to ensure it'll fetch without blocking render
ss.media = "only x";
// inject link
ref.parentNode.insertBefore( ss, ref );
// set media back to `all` so that the styleshet applies once it loads
setTimeout( function(){
ss.media = media || "all";
} );
}
Jetzt müsst ihr nur noch an passender Stelle die loadCSS()-Funktion aufrufen und als Parameter den Pfad zur CSS-Datei übergeben. Das kann dann so aussehen: loadCSS( "style.css" );. Das wars schon. Jetzt könnt ihr beispielsweise Stylesheets von Plugins, etwa einer Lightbox, asynchron nachladen, indem ihr den Aufruf der loadCSS()-Funktion vor das schließende body-Tag stellt. Dadurch verhindert ihr, dass die CSS-Datei direkt beim Seitenaufruf eine der wenigen zeitgleich offenen Server-Verbindungen blockiert oder euer Haupt-Stylesheet unnötig größer wird, wenn ihr die CSS-Dateien einfach in einer großen Datei zusammenführen würdet.
Aktuell gibt es noch das Problem, dass eine CSS-Datei mehrfach nachgeladen werden kann. Wenn beispielsweise eine CSS-Datei durch den Klick eines Links nachgeladen werden soll und dieser Link ein weiteres Mal angeklickt wird, dann steht die CSS-Datei zweimal im head-Element. Auf GitHub gibt es aber bereits einen entsprechenden Pull Request, der bei einem kurzen Test auch funktioniert hat.












von michsch am 23.06.2014 (16:15 Uhr)
Google Page Speed empfiehlt das sogar nicht nur für Plugins, welche tatsächlich nicht beim ersten Laden direkt sichtbar sind (z.B. Lightbox), sondern für alle Inhalte, die keine "above the fold"-Inhalte sind.
TeilenDas heißt, dass man laut Google nur das CSS initial laden sollte, welches wirklich nur das grobe Seitenlayout enthält. Andere Design-Elemente, Web-Fonts oder als Data-URI eingebundene Hintergrundgrafiken sollten asynchron geladen werden. Ich habe dafür allerdings noch keinen annehmbaren Workflow gefunden, aber ich bin auf der Suche. Mit Sass, Compass und Grunt sollte sich das immerhin realisieren lassen.
von Bluebird101 am 24.06.2014 (11:45 Uhr)
Dass Google Page Speed das empfiehlt, scheint ja recht neu zu sein. Bis vor Kurzem wurde das, soweit ich mich erinnern kann, noch nicht vorgeschlagen.
TeilenAlternativ könnte man das auch mit einem PHP-Skript realisieren. Je nach eingesetzter Software buffert man zunächst sämtliche Inhalte, extrahiert dann mit PHP alle benötigt CSS-Klassen und -IDs und kann anschließend einen Teil auslagern und einen Teil des Stylesheets direkt inline einbetten. Fraglich ist jedoch, wie gut bei einer solchen Methode dann die Performance ist.
von irgendeinem Spinner am 24.06.2014 (14:29 Uhr)
@Bluebird101
TeilenFür Nodejs/Grunt/Gulp gibt es sowas schon fertig: https://github.com/pocketjoso/penthouse
von Jens Richter am 24.06.2014 (15:27 Uhr)
Sehr schön. Was passiert, wenn JavaScript deaktiviert ist?
Teilenvon JenZzzz am 24.06.2014 (17:57 Uhr)
@Jens Richter: habe ich mich auch gefragt, gibts hierfür auch eine Fallback-Lösung? Dann wäre ich auch sofort dabei ...
Teilenvon Philipp Blum am 24.06.2014 (23:57 Uhr)
Jen, die Antwort ist recht einfach: Dann hat die Person Pech gehabt. Es gibt einfach kaum eine Seite im Web, die ordentlich ohne Javascript funktioniert. Nur ca 0.1% - 2% der Nutzter haben Javascript deaktiviert. In den meisten Fällen gehören diese Leute nicht einmal zu deiner Zielgruppe. Also diese Leute kann man getrost übergehen.
Teilenvon fzgg am 25.06.2014 (12:15 Uhr)
Genau unobstrusive und barrierefrei ist totaler Quatsch.
Teilenvon JenZzzz am 25.06.2014 (14:27 Uhr)
@ Philipp: ich erstelle jede Seite so, dass diese auch ohne Javascript funktioniert, bzw. man zumindest die Inhalte vernünftig lesen kann. Wenn dieses Bildergewackel (ala jquery und Co.) nicht funktioniert, ist mir das egal, aber wenn die Seite völlig unformatiert angezeigt wird, weil das CSS fehlt, finde ich das nicht so schick. Und deswegen kann mich google an der Stelle auch mal am *** lecken ;)
Teilen