Das könnte dich auch interessieren

Du hast deinen AdBlocker an?

Es wäre ein Traum, wenn du ihn für t3n.de deaktivierst. Wir zeigen dir gerne, wie das geht. Und natürlich erklären wir dir auch, warum uns das so wichtig ist. Digitales High-five, deine t3n-Redaktion

Entwicklung

CSS-Stylesheets asynchron nachladen – so gehts!

    CSS-Stylesheets asynchron nachladen – so gehts!

Asynchrones Nachladen von CSS mit loadCSS. (Screenshot: GitHub)

Häufig benötigt ihr einen Teil des CSS nicht gleich zu Beginn des ersten Seitenaufrufs. Wir stellen euch ein kleines Snippet vor, das ein asynchrones Nachladen von CSS-Dateien ermöglicht.

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.

Finde einen Job, den du liebst zum Thema Webdesign, Webentwickler

15 Reaktionen
MPiontek
MPiontek

Inline -.- das ist aber nicht so schön. Naja, ich habe es jetzt ans Ende, kurz vor den Body gesetzt und auf async gesetzt. Ich verstehe zwar nicht warum, aber es funktioniert.

Antworten

Florian Brinkmann

Bei Performance-Optimierung geht es manchmal nicht darum, ob eine Lösung „schön“ ist :) Bei dem Critical CSS muss der kritische Teil ja auch inline eingefügt werden. Auch vielleicht nicht die schönste Methode aber schnell.

Antworten

MPiontek
MPiontek

Joar, ich gebe gerne schön Lösungen weiter. Wie gesagt, es ließ sich an der Stelle ja beheben. Das inline CSS werde ich zwar nicht los, aber ich muss es ja nicht auf die Spitze treiben :D

MPiontek
MPiontek

Toll, und dann habe ich im Head das nächste Script, dass mein Rendering blockiert. Was ist das denn für eine Logik? Warum muss man es im Head laden, da verstehe ich nicht.

Antworten

Florian Brinkmann

Wieso hast du bei einem Inline-Script eine Blockade des Rendering?

Antworten

JenZzzz
JenZzzz

@ 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 ;)

Antworten

fzgg
fzgg

Genau unobstrusive und barrierefrei ist totaler Quatsch.

Antworten

Philipp Blum
Philipp Blum

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.

Antworten

JenZzzz
JenZzzz

@Jens Richter: habe ich mich auch gefragt, gibts hierfür auch eine Fallback-Lösung? Dann wäre ich auch sofort dabei ...

Antworten

Jens Richter
Jens Richter

Sehr schön. Was passiert, wenn JavaScript deaktiviert ist?

Antworten

florence.maurice
florence.maurice

Damit die Anzeige auch bei deaktiviertem JavaScript funktioniert, kann man das Stylesheet zusätzlich innerhalb von noscript einbinden.

Antworten

irgendeinem Spinner
irgendeinem Spinner

@Bluebird101

Für Nodejs/Grunt/Gulp gibt es sowas schon fertig: https://github.com/pocketjoso/penthouse

Antworten

Bluebird101
Bluebird101

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.

Alternativ 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.

Antworten

michsch
michsch

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.
Das 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.

Antworten

Killah_Chinchillah
Killah_Chinchillah

http://autoprefixer.github.io/
liefert den CSS-Code, der above-the-fold benötigt wird.

Ausserdem gibt es von Google dazu ein Apache-Modul, dass den Code jeder herkömmlichen HTML-Seite vor ihrer Auslieferung modifiziert;
https://github.com/pagespeed/mod_pagespeed

Allerdings habe ich noch keinen Provider gefunden, der bereit war dies zu installieren.

Frank Hübner
(Senior Programmer)
http://www.binary-garden.com

Antworten

Melde dich mit deinem t3n-Account an oder fülle die unteren Felder aus.

Abbrechen