HGVision
GAMES DESIGN DEVELOPMENT

CSS asynchron laden mit loadCSS

Viele die im Bereich Webentwicklung oder Frontend Entwicklung arbeiten kennen das kleine Problem wenn es an die Perfomance einer Seite geht. Warum ist die so wichtig? Weil Google Seiten mit schlechter Perfomance abstraft. Und deshalb kennen auch viele Entwickler Googles Pagespeed.

Pagespeed zeigt einem von an wie schnell die Inhalte einer Seite geladen werden können und wie schnell eine Seite gerendert werden kann. Neben Server seitigen Anpassungen kommen aber auch viele Dinge zum tragen die jeder Entwickler umsetzen kann.

CSS, HTML und JS reduzieren und minimieren. Bilder optimieren, Browser caching nutzen usw. Eine Regel nach der Google eine Seite bewertet scheint aber immer wieder für Kopfzerbrechen zu sorgen und zwar:JavaScript- und CSS-Ressourcen, die das Rendering blockieren, in Inhalten "above the fold" (ohne Scrollen sichtbar) beseitigen.

An sich ist die Regel relativ einfach für jeden Entwickler zu berücksichtigen, man packt alles das an CSS und JS, welches man benötigt um eine Seite ohne Scrollen anzuzeigen, direkt mit in eine Seite hinein.

Nun haben wir in all den Jahren immer wieder gelernt: CSS in eigene Dateien auslagern. Wer das macht wir definitiv von Googles Regel lesen wenn er seine Seite testet.

Man kann aber auch die Seite für Google optimieren ohne nun alles aus seiner CSS Datei heraus zu nehmen und es direkt mit in den Kopf der HTML Datei zu packen.

Hier kann einem ein kleines Stück Javascript weiterhelfen. loadCSS von Scott Jehl. Zu finden gib es den Code bei Github.

Um die Funktion zu nutzen muss man nichts mehr machen als die JS Funktion in die Seite zu packen wo man CSS asynchron laden möchte und dann ruft man die Funktion mit dem Pfad zur CSS-Datei als Parameter auf.

Beispiel:


/*!
        loadCSS: load a CSS file asynchronously.
        [c]2015 @scottjehl, Filament Group, Inc.
        Licensed MIT
        */
        (function(w){
                "use strict";
                /* exported loadCSS */
                w.loadCSS = function( href, before, media ){
                        // Arguments explained:
                        // `href` [REQUIRED] is the URL for your CSS file.
                        // `before` [OPTIONAL] is the element the script should use as a reference for injecting our stylesheet  before
                                // By default, loadCSS attempts to inject the link after the last stylesheet or script in the DOM. However, you might desire a more specific location in your document.
                        // `media` [OPTIONAL] is the media type or query of the stylesheet. By default it will be 'all'
                        var doc = w.document;
                        var ss = doc.createElement( "link" );
                        var ref;
                        if( before ){
                                ref = before;
                        }
                        else {
                                var refs = ( doc.body || doc.getElementsByTagName( "head" )[ 0 ] ).childNodes;
                                ref = refs[ refs.length - 1];
                        }

                        var sheets = doc.styleSheets;
                        ss.rel = "stylesheet";
                        ss.href = href;
                        // temporarily set media to something inapplicable to ensure it'll fetch without blocking render
                        ss.media = "only x";

                        // Inject link
                                // Note: the ternary preserves the existing behavior of "before" argument, but we could choose to change the argument to "after" in a later release and standardize on ref.nextSibling for all refs
                                // Note: `insertBefore` is used instead of `appendChild`, for safety re: http://www.paulirish.com/2011/surefire-dom-element-insertion/
                        ref.parentNode.insertBefore( ss, ( before ? ref : ref.nextSibling ) );
                        // A method (exposed on return object for external use) that mimics onload by polling until document.styleSheets until it includes the new sheet.
                        var onloadcssdefined = function( cb ){
                                var resolvedHref = ss.href;
                                var i = sheets.length;
                                while( i-- ){
                                        if( sheets[ i ].href === resolvedHref ){
                                                return cb();
                                        }
                                }
                                setTimeout(function() {
                                        onloadcssdefined( cb );
                                });
                        };

                        // once loaded, set link's media back to `all` so that the stylesheet applies once it loads
                        ss.onloadcssdefined = onloadcssdefined;
                        onloadcssdefined(function() {
                                ss.media = media || "all";
                        });
                        return ss;
                };
                // commonjs
                if( typeof module !== "undefined" ){
                        module.exports = w.loadCSS;
                }
        }(this));
/* Deine CSS Dateien die asynchron geladen werden sollen */ loadCSS( "css/style.css" ); loadCSS( "css/font.css" );

Ab da werden die CSS Dateien asynchron geladen und das rendering wird nicht mehr blockiert. So kann man bei Pagespeed noch ein gutes Stück näher an die 100 Punkte kommen.

 Pagespeed Ergebnis hgvision.de