Jeden z największym problemów podczas optymalizacji (pod kątem szybkości ładowania) bloga na WordPressie, zresztą także i na innych CMS’ach, jest to, że nie można ładować natywnie CSS’ów asynchronicznie.
Ostatnio pisałem o sposobach na ładowanie JavaScript’ów asynchronicznie i tutaj sprawa wyglądała bardzo prosto – wystarczyło dopisać async do kodu i z głowy. Jednak w przypadku ładowania arkuszy stylów nie ma lekko, nie ma prostego rozwiązania.
Z drugiej strony, jeśli sprawdzimy prosty JavaScript, który przygotował dla Nas Scott Jehl to znajdziemy w nim rozwiązanie na tyle proste, że każdy, nawet początkujący blogger, poradzi sobie z jego implementacją.
Wielu z Was zastanawia się po jakiego groma ładować asynchronicznie CSS’y, przecież to może nieźle namieszać podczas generowania witryny. I macie poniekąd rację, choć z drugiej strony czemu nie zrobić tego jeśli mowa o ładowaniu czcionek? Można także zostawić w spokoju kod odpowiedzialny za ładowanie wszystkiego co jest w zasięgu tzw. „above the fold”, a całą resztę ładować asynchronicznie.
Możemy umieścić style w tzw. stopce strony, ale to nie sprawi, że będą one ładować się asynchronicznie. Metoda ta jedynie opóźni w czasie to co nieuniknione, czyli ich ładowanie, jeden arkusz za drugim.
Wreszcie powróćmy do tego co przyszykował na Scott Jehl, a dokładnie do funkcji loadCSS. Prosty kod JavaScript pozwalający ładować nam CSS’y asynchronicznie. Używałem tego kody na wielu stronach, niekoniecznie opartych o WordPressa i działa on doskonale, ale mimo wszystko używać go trzeba z głową.
Kod znajdziecie poniżej, skopiujcie go:
<script>/*! loadCSS: load a CSS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. Licensed MIT */ /* exported loadCSS */ function loadCSS( href, before, media, callback ){ "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 ]; var sheets = window.document.styleSheets; 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"; // DEPRECATED if( callback ) { ss.onload = callback; } // inject link ref.parentNode.insertBefore( ss, ref ); // This function sets the link's media back to `all` so that the stylesheet applies once it loads // It is designed to poll until document.styleSheets includes the new sheet. ss.onloadcssdefined = function( cb ){ var defined; for( var i = 0; i < sheets.length; i++ ){ if( sheets[ i ].href && sheets[ i ].href === ss.href ){ defined = true; } } if( defined ){ cb(); } else { setTimeout(function() { ss.onloadcssdefined( cb ); }); } }; ss.onloadcssdefined(function() { ss.media = media || "all"; }); return ss;</script>
Następnie wklejcie to co skopiowaliście do sekcji head swojej strony, tuż przed innymi skryptami.
Dobrze jest też dodać tag noscript, aby obsłużyć osoby sprzed epoki kamienia, które w przeglądarkach małą wyłączoną obsługę JavaScript i tym samym zaserwować im potrzebne style.
[sociallocker] Domyślnie funkcja wstawi arkusz stylów przed pierwszym tagiem <script> w DOM. Jeśli nie chcecie tam to możecie sami zdecydować gdzie funkcja ma go umieścić definiując parametr „before”:
loadCSS( "/css/style.css", window.document.getElementsByTagName( 'script' )[ 2 ] );
Pozwoli wam to wstawić style po trzecim wystąpieniu tagu <script> zamiast przed pierwszym.[/sociallocker]
Parametr „media” to już chyba każdy kojarzy i funkcja domyślnie ustawia go jako media=”all”
Przykładowe użycie funkcji macie poniżej:
<script> loadCSS( "/css/style.css" );</script>
<noscript><link rel="stylesheet" href="/css/style.css"</noscript>
Także powodzenia.
a miało być tak prosto… 🙁
A co się popsuło, co nie tak?
pytanko: ten skrypt mozna wywolac z osobnego pliku? czy musi byc w head?