Hier ist der Knackpunkt: Wenn Sie JavaScript von Drittanbietern laden, sollten Sie dies asynchron tun. Möglicherweise möchten Sie auch Ihre eigenen Skripte asynchron laden, aber konzentrieren wir uns in diesem Artikel auf Drittanbieter.
Dafür gibt es zwei Gründe
- Wenn der Drittanbieter ausfällt oder langsam ist, wird Ihre Seite nicht durch das Laden dieser Ressource aufgehalten.
- Es kann die Ladezeiten von Seiten beschleunigen.
Bei Wufoo haben wir gerade umgestellt auf ein asynchrones Einbettungs-Snippet. Benutzer, die Formulare mit Wufoo erstellen und sie auf ihrer Website einbetten möchten, werden nun empfohlen, es zu verwenden. Wir haben dies aus genau diesen genannten Gründen getan. Es ist das Verantwortungsvollste, was ein Webdienst tun kann, der Leute bittet, sich auf Ressourcen auf der Website dieses Dienstes zu beziehen.
Lassen Sie uns dieses ganze Async-Thema untersuchen.
Äh. Was?
Hier gibt es ein wenig Terminologie, die uns helfen wird, den Überbegriff „asynchron“ zu verstehen.
„Parser-blocking“ – Der Browser liest Ihr HTML und wenn er auf ein <script>-Tag stößt, lädt er diese gesamte Ressource herunter, bevor er mit dem Parsen fortfährt. Das verlangsamt definitiv die Seitenladezeiten, insbesondere wenn sich das Skript im Head-Bereich oder über anderen visuellen Elementen befindet. Dies gilt sowohl für ältere als auch für moderne Browser, wenn Sie das async-Attribut nicht verwenden (dazu später mehr). Aus den MDN-Dokumenten: „In älteren Browsern, die das async-Attribut nicht unterstützen, blockieren vom Parser eingefügte Skripte den Parser…“
Um problematisches Parser-Blocking zu verhindern, können Skripte „script-inserted“ (d. h. ein weiteres Skript mit JavaScript einfügen) sein, die dann deren Ausführung erzwingen (außer in Opera oder vor Firefox 4.0).
„Ressourcen-Blocking“ – Während ein Skript heruntergeladen wird, kann es andere Ressourcen daran hindern, gleichzeitig mit ihm heruntergeladen zu werden. IE 6 und 7 tun dies und erlauben nur den Download eines Skripts gleichzeitig und nichts anderes. IE 8 und Safari 4 erlauben den gleichzeitigen Download mehrerer Skripte, blockieren aber alle anderen Ressourcen (Referenz).
Idealerweise kämpfen wir gegen beide Probleme und beschleunigen die Ladezeiten von Seiten (sowohl tatsächliche als auch wahrgenommene).
Der HTML5-Weg
Es gibt ein async-Attribut für das script-Tag in HTML5 (Spezifikation). Beispiel
<script async src="https://third-party.com/resource.js"></script>
Die Browserunterstützung dafür ist Firefox 3.6+, IE 10+, Chrome 2+, Safari 5+, iOS 5+, Android 3+. Noch keine Opera-Unterstützung.
Wenn Sie ein Skript direkt auf diese Weise laden möchten, ist die Verwendung dieses Attributs wahrscheinlich eine gute Idee. Es verhindert Parser-Blocking. Diese neueren Browser haben keine großen Probleme mit Ressourcen-Blocking, aber das Parser-Ding ist eine große Sache. Wir verwenden dies bei Wufoo nicht, da wir eine weitaus tiefere Browserunterstützung benötigen.
Der klassische Async-Weg
Hier ist das grundlegende Muster zum asynchronen Laden von Skripten, das Ihnen die größtmögliche Browserunterstützung bietet, die Sie jemals benötigen werden
<script>
var resource = document.createElement('script');
resource.src = "https://third-party.com/resource.js";
var script = document.getElementsByTagName('script')[0];
script.parentNode.insertBefore(resource, script);
</script>
Hier ist eine effizientere Version mit einer Wrapper-Funktion um diese Variablen herum (Quelle Mathias Bynens)
(function(d, t) {
var g = d.createElement(t),
s = d.getElementsByTagName(t)[0];
g.src = 'https://third-party.com/resource.js';
s.parentNode.insertBefore(g, s);
}(document, 'script'));
async-Attribut verwenden.Werbenetzwerke
BuySellAds ist ein Werbenetzwerk, das eines der ersten war, das Anzeigen asynchron ausgeliefert hat. Dies ist ihr Muster
<script type="text/javascript">
(function(){
var bsa = document.createElement('script');
bsa.type = 'text/javascript';
bsa.async = true;
bsa.src = 'https://#/ac/bsa.js';
(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(bsa);
})();
</script>
Ein paar Dinge, die hier zu beachten sind
- Sie setzen das
async-Attribut des Skripts auf true, bevor sie es anhängen. Dies ist ausschließlich für Firefox 3.6 nützlich, da dies der einzige Browser ist, der dies nicht standardmäßig tut. Dies kann wahrscheinlich in den meisten Szenarien weggelassen werden. Das Setzen des Skriptstypeist definitiv nicht erforderlich. - Wie im einfachen Muster oben wird die
srcmit einer protokollrelativen URL gesetzt. Dies ist eine sehr nützliche Möglichkeit, das Skript entweder über HTTP oder HTTPS zu laden, abhängig von der Seite, die es angefordert hat. Wir müssen dies bei Wufoo unbedingt tun, haben aber leider festgestellt, dass es in IE 6 mit den Standard-Sicherheitseinstellungen einen Fehler verursacht. Wenn Sie keine IE 6-Unterstützung benötigen, verwenden Sie es auf jeden Fall. - Sie fügen das Skript entweder in den Kopf oder in den Körper ein, je nachdem, was zuerst gefunden wird. Eine völlig in Ordnung Art, dies zu tun, aber genauso sicher ist es, nach einem Skriptelement zu suchen, da der Code selbst ein Skriptelement ist.
The Deck verwendet ein anderes Muster
<script type="text/javascript">
//<![CDATA[
(function(id) {
document.write('<script type="text/javascript" src="' +
'http://connect.decknetwork.net/deck' + id + '_js.php?' +
(new Date().getTime()) + '"></' + 'script>');
})("DF");
//]]>
</script>
Ich bin ziemlich sicher, dass dies immer noch als asynchron gilt, da die Ressource, die sie laden, ein skript-injiziertes Skript ist, was bedeutet, dass es nicht den Parser blockiert.
Was ist, wenn Sie einen Callback benötigen?
Manchmal müssen Sie ein Skript von Drittanbietern laden und dann, sobald dieses Skript geladen ist, benutzerdefinierten Code ausführen. Dieser benutzerdefinierte Code ruft wahrscheinlich eine Funktion auf, die im Skript des Drittanbieters definiert ist, mit Daten, die für eine bestimmte Seite spezifisch sind.
<script src="https://third-party.com/resource.js"></script>
<script>
doSomethingFancy('chriscoyier');
</script>
Typekit befindet sich in dieser Situation. Sie müssen das Typekit-JavaScript laden und es dann starten. Typekit nutzt tatsächlich die Tatsache, dass Skripte den Parser blockieren. Wenn Ihre Seite verzögert wird, bis ihr Skript geladen ist, sehen Sie nicht den „FOUT“ (Flash Of Unstyled Text), der normalerweise nur in Firefox problematisch ist, aber auch bei Typekit problematisch ist, wo @font-face-Ressourcen über JavaScript geladen werden.
<script type="text/javascript" src="https://use.typekit.com/abc1def.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
Das ist clever, aber auch ein wenig gefährlich. Wenn Typekit ausfällt oder langsam ist: „Was einst eine erwünschte Verzögerung beim Rendern war, um den FOUT zu verbergen, wird zu einem ernsten Problem, wenn das Skript länger als ein paar Sekunden zum Laden benötigt.“ (Referenz).
Hier ist eine Möglichkeit, Typekit asynchron zu laden
<script type="text/javascript">
TypekitConfig = {
kitId: 'abc1def'
};
(function() {
var tk = document.createElement('script');
tk.src = 'https://use.typekit.com/' + TypekitConfig.kitId + '.js';
tk.type = 'text/javascript';
tk.async = 'true';
tk.onload = tk.onreadystatechange = function() {
var rs = this.readyState;
if (rs && rs != 'complete' && rs != 'loaded') return;
try { Typekit.load(TypekitConfig); } catch (e) {}
};
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(tk, s);
})();
</script>
Es gibt sehr viel komplizierter Code, um den Onload-Callback zu behandeln. Das ist einfach so, um Callbacks mit tiefgehender Browserunterstützung zum Laufen zu bringen, leider. Seien Sie gewarnt, die Verwendung dieses Musters bringt das Problem von FOUT zurück. Wenn Sie mit Typekit asynchron vorgehen und die gleiche gute Erfahrung wie normal haben möchten, lesen Sie ihren Beitrag dazu, der einige clevere Klassenmanipulationen und Schriftartenereignisse abdeckt.
jQuery und andere Skriptlader
Wenn Sie bereits jQuery verwenden, ist das Laden eines Drittanbieter-Skripts und das Erhalten eines Callbacks, wenn es bereit ist, ziemlich einfach
$.ajax({
url: 'https://third-party.com/resource.js',
dataType: 'script',
cache: true, // otherwise will get fresh copy every page load
success: function() {
// script loaded, do stuff!
}
}
Ich bin sicher, dass andere Bibliotheken ähnliche Fähigkeiten haben. Das ist die klassische Sache, bei der JavaScript-Bibliotheken helfen können. Sehen Sie sich auch getScript an, das etwas prägnanter sein mag.
Wenn Sie keine Bibliothek verwenden und sich Sorgen über die Dateigröße machen, ist YepNope ein extrem kleines Skript, das auch helfen kann. Sein idealer Einsatz ist die Durchführung eines Tests, um festzustellen, ob Sie das Skript laden müssen oder nicht, aber es hat auch direkte Methoden
yepnope.injectJs("https://third-party.com/resource.js", function () {
// script loaded, do stuff!
});
Relevant: Artikel von Max Wheeler Loading Typekit Asynchronously with YepNope.
Brauchen Sie wirklich einen Callback?
Bei Wufoo haben wir herausgefunden, dass ja, wir brauchen einen Callback. Wir müssen die JavaScript-Ressource für die Formular-Einbettung laden und dann eine Funktion mit allen Details des Formulars des Benutzers aufrufen. So haben wir es früher gemacht
<script type="text/javascript">var host = (("https:" == document.location.protocol) ? "https://secure." : "http://");document.write(unescape("%3Cscript src='" + host + "wufoo.com/scripts/embed/form.js' type='text/javascript'%3E%3C/script%3E"));</script><br />
<script type="text/javascript">
var z7p9p1 = new WufooForm();
z7p9p1.initialize({
'userName':'chriscoyier',
'formHash':'z7p9p1',
'autoResize':true,
'height':'546',
'ssl':true});
z7p9p1.display();
</script>
Diese Menge an Schlüssel/Wert-Paaren ist nützlich für einen Benutzer, um Dinge zu sehen, zu ändern und hinzuzufügen. Wir haben mit einigen Wegen herumgespielt, wie wir das beibehalten könnten, aber diese Daten als Teil der URL beim Aufruf des Skripts übergeben. Das Skript auf unserer Seite wäre eigentlich PHP und könnte die Werte per $_GET abrufen. Das würde die Notwendigkeit vermeiden, sich mit dem ganzen hässlichen Callback-Code in einem asynchronen Muster zu befassen. Möglicherweise etwas wie
script.src = 'https://wufoo.com/form.js?data=' + JSON.stringify(options);
Aber letztendlich haben wir uns dagegen entschieden. Der Callback-Code ist nicht so schlecht, das Stringifying von JSON hat keine sehr tiefe Browserunterstützung (und es ist unpraktisch, einen Polyfill in Copy-Paste-Code aufzunehmen), und es ist ideal, dass unser form.js gut zwischengespeichert wird.
Soziale Medien
Buttons für soziale Medien sind ein klassischer Fall für die Notwendigkeit von Drittanbieter-JavaScript auf Ihrer Seite. Interessanterweise stellen die drei größten Anbieter ihren Code bereits in einem asynchronen Muster bereit.
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "https://#/en_US/all.js#xfbml=1&appId=200103733347528";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
<a href="https://twitter.com/share" class="twitter-share-button">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
Google Plus
<g:plusone annotation="inline"></g:plusone>
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
Aufräumen
Alle oben genannten sind sehr ähnlich und doch leicht unterschiedlich. Wenn man sie alle so, wie sie sind, auf eine Seite wirft, können Code-Puristen wie wir weinen. Nicholas Gallagher hat eine wirklich saubere und effiziente Methode, sie alle zusammenzufügen
(function(doc, script) {
var js,
fjs = doc.getElementsByTagName(script)[0],
add = function(url, id) {
if (doc.getElementById(id)) {return;}
js = doc.createElement(script);
js.src = url;
id && (js.id = id);
fjs.parentNode.insertBefore(js, fjs);
};
// Google Analytics
add('https:://#/ga.js', 'ga');
// Google+ button
add('https://apis.google.com/js/plusone.js');
// Facebook SDK
add('https://#/en_US/all.js', 'facebook-jssdk');
// Twitter SDK
add('https://platform.twitter.com/widgets.js', 'twitter-wjs');
}(document, 'script'));
Umgang mit CMS
WordPress ist riesig. Ebenso alle anderen großen CMS. Sie können nicht ignoriert werden, wenn Sie ein Drittanbieter sind, der Copy-Paste-JavaScript-Code anbietet. Der Schlüssel ist natürlich das Testen. Das Wichtigste ist, keine doppelten Zeilenumbrüche innerhalb des Codes einzufügen. Wie
<script type="text/javascript">
var s = d.createElement(t), options = {
foo: bar
}
// The line break space above is bad!
</script>
Das mag schön und sauber aussehen, aber das „autop“-Verhalten von WordPress fügt überall im Code Absatz-Tags ein, was natürlich verhindert, dass das Skript wie erwartet ausgeführt wird.
Finale Wufoo-Snippet
Das ist es, was wir am Ende hatten
<div id="wufoo-z7w3m7">
Fill out my <a href="http://examples.wufoo.com/forms/z7w3m7">online form</a>.
</div>
<script type="text/javascript">var z7w3m7;(function(d, t) {
var s = d.createElement(t), options = {
'userName':'examples',
'formHash':'z7w3m7',
'autoResize':true,
'height':'260',
'async':true,
'header':'show',
'ssl':true};
s.src = 'https://wufoo.com/scripts/embed/form.js';
s.onload = s.onreadystatechange = function() {
var rs = this.readyState; if (rs) if (rs != 'complete') if (rs != 'loaded') return;
try { z7w3m7 = new WufooForm();z7w3m7.initialize(options);z7w3m7.display(); } catch (e) {}};
var scr = d.getElementsByTagName(t)[0], par = scr.parentNode; par.insertBefore(s, scr);
})(document, 'script');</script>
Ehrlich gesagt, die „Größe“ des Snippets war ein Problem. Fünfzig Zeilen sind für so etwas einfach zu viel. Es sind jetzt 19, was mehr ist als wir hatten, aber akzeptabel ist. Viele dieser Zeilen sind das Options-Objekt, das wir in weniger Zeilen quetschen könnten, aber es ist schöner, sie für Lesbarkeit und Änderbarkeit jeweils auf separaten Zeilen zu haben.
Wir müssen IE 6 weiterhin unterstützen, also leider keine protokollrelativen URLs für uns. Wir verwenden den location.protocol-Test.
Es ist etwas größer als Ihr „durchschnittliches“ Async-Snippet (wenn es so etwas wie ein durchschnittliches Snippet gibt), aber das ist in Ordnung. Es hat ziemlich viel zu tun und erledigt es gut.
Wir sprechen über eine Reihe der Vorteile in der Ankündigungs-Blogpost. Mein Favorit ist, dass Sie das Skript jetzt überallhin verschieben können, wo Sie möchten. Es muss nicht genau dort platziert werden, wo das Formular erscheinen soll, wie es früher der Fall war.
Wasserfälle
Wenn Sie daran interessiert sind, Ressourcen-Ladevorgänge zu testen, ist die Betrachtung von Ressourcen-Wasserfällen besonders nützlich. Moderne Web-Entwicklertools haben dies integriert, wie z. B. die Registerkarte „Network“ im Web-Inspektor oder die Registerkarte „Net“ von Firebug. Aber die alten Entwicklertools in IE 6-8 bieten diese Informationen nicht. Glücklicherweise tut die Website Web Page Test dies (sie ist etwas hässlich, aber sehr cool).
Während ich für das Wufoo-Snippet in IE 6 Tests durchführte, konnte ich beweisen, dass unsere neue Methode nicht blockiert und die alte stark blockiert hat


So, das ist alles, was ich habe. Ich fühle mich etwas komisch dabei, über all diese Dinge zu schreiben, da sie für mich noch recht neu sind und ich das Gefühl habe, weit davon entfernt zu sein, ein Experte zu sein. Fühlen Sie sich also frei, mich bei allem zu korrigieren oder Ihre eigenen Erfahrungen mit Async zu teilen.
Wo passt das
defer-Attribut in das alles hinein? Es startet den (nicht blockierenden, oder?) Download sofort, wartet aber, bis die Seite geparst ist, bevor sie ausgeführt wird, und wenn ich mich richtig erinnere, hat es auch den Vorteil, dass es in der richtigen Reihenfolge ausgeführt wird.Auch ich könnte mich irren, aber ich glaube, ein Problem, das es vermeidet, ist, dass die Ausführung das Parsen (und/oder vielleicht das Reflowing...?) unterbricht… Es scheint, dass ein großes/komplexes
<script async>, das mitten im Parsen geladen wird, einige Probleme verursachen würde.Die Browserunterstützung für
deferist sehr schlecht. IE hat es erfunden, aber selbst IE8 führt deferred Skripte nicht immer in der richtigen Reihenfolge aus. Andere moderne Browser haben begrenzte, fehlerhafte oder keine Unterstützung.Referenzen
mozilla.org
sitepoint.com
Verwenden Sie stattdessen
window.onload()(oder Bibliotheksfunktionen wie die$(document).ready()-Methode von jQuery).Chris, Sie haben YepNope erwähnt, aber das Skript, mit dem ich mich wohler fühle, ist LABjs: http://labjs.com/ (es gibt inzwischen ziemlich viele davon).
Wow, das kannte ich gar nicht! Danke :)
Ich bin daran interessiert, welche Art von Fehlern aufgetreten sind und wie Sie das getestet haben.
Bei Wikipedia haben wir fast alles auf Protokoll-URLs umgestellt seit Herbst/Winter 2011 und unterstützen IE6 so gut wie möglich. Ich erinnere mich nicht an Warnungen (getestet auf http und https).
Was halten Sie von diesem Skript zum parallelen Laden von JS: http://headjs.com/
Ich denke, das ist auch eine großartige Möglichkeit, JS zu laden
Ich bin auch ein großer Fan von headjs, auch wenn es manchmal wirklich schwierig ist, es zum Gehorchen zu bringen.
Für asynchrones Skriptladen habe ich mich kürzlich für RequireJS entschieden, das ich bei einigen Projekten verwendet habe und das sich bei der Betrachtung der Netzwerkergebnisse als recht konsistent erwiesen hat.
Chris, ich bin überrascht, dass Sie Require.js nicht erwähnt haben! Warum haben Sie sich dagegen entschieden?
Kann mir jemand ein wenig beim asynchronen Laden von Social-Buttons von Nicolas Gallagher helfen? Ich muss `async=1` in das Skript einfügen, weiß aber nicht, wann ich es brechen würde.
https://gist.github.com/1025811
@Teddy Cross Wenn Sie sich für das
defer-Attribut interessieren, empfehle ich Ihnen dringend, die Diskussion über Paul Irishs Lazy Web Request – Issue #42 zu lesen.https://github.com/paulirish/lazyweb-requests/issues/42
Wenn Sie sich nicht die Mühe machen wollen, auf den Link zu klicken. Paul fasste es mit diesen weisen Worten zusammen
Hoffe, das hilft.
Oh, und großartiger Beitrag, Chris!
Hallo Chris,
Eigentlich nein, wenn Sie ein Skriptelement mit
document.writeauf diese Weise einfügen, blockiert der Parser das neu hinzugefügte Skriptelement. Dies ist eine sehr gängige Methode, um weitere blockierende Skripte hinzuzufügen. Sie können es hier ausprobieren (Quelle).Beste Grüße,
— T.J.
Wissen Sie, ob es möglich ist, Google AdSense asynchron zu laden? Ich habe letzte Woche ein paar Dinge mit window.onload versucht, aber es hat überhaupt nicht funktioniert.
Wenn Sie den aktuellen Anzeigen-Code verwenden, ist dieser bereits asynchron.
http://www.webmaster-source.com/2011/03/18/google-rolling-out-asynchronous-adsense-ads/
Aber es ist nur asynchron, *nachdem* das show_ads.js-Skript überhaupt geladen wurde, was synchron erfolgt.
Ich denke, es ist wichtig zu erwähnen, dass JavaScript mit
document.write()(sehr üblich bei der Arbeit mit Drittanbieter-Skripten) nicht asynchron geladen werden kann. Zumindest nicht ohne Hacks.Zum Beispiel rendert das Beispiel von The Deck nicht asynchron, da das Skript
document.write()verwendet, um die Anzeige einzufügen. Das Laden und Parsen wird blockiert. Deshalb rendern Websites wie Daring Fireball nicht, wenn das The Deck-Netzwerk ausfällt.Hier ist eine Demo-Seite, die zeigt, was passiert, wenn ein Skript mit
document.write()mitdocument.write()eingefügt wird. Die Antwort pausiert 3 Sekunden, um das Blocking zu demonstrieren.http://www.ravelrumba.com/code/demos/blocking-ads/demo-blocking2.html
Wie auch immer, der Punkt ist nur, dass eine gewisse Zusammenarbeit mit dem externen Skript, das Sie laden, erforderlich ist, um Asynchronität zu gewährleisten.
hinclude.js ist eine großartige Bibliothek zum Einfügen von asynchronen Inhalten.
http://mnot.github.com/hinclude/
document.write ist böse… aber es scheint, als ob es immer noch parallel geladen wird, wenn auch mit einigen Tücken: http://stevesouders.com/cuzillion/?ex=10014
So cooler Artikel, danke!! Besonders mit dem Panda- und Caffeine-Update ist die Seitenladezeit wichtiger denn je… Seite als Lesezeichen markiert ;-)
Ich liebe den Artikel. Typekit schien schon immer ein gefährliches Skript zu sein, das so geladen wird, wie sie das Einbetten anbieten. Ich habe async (sehr ähnlich zu Ihrem obigen Snippet) verwendet, um es zu laden, bekomme aber immer noch den FOUT. Ich mag den Link zu ihrem Artikel über Klassenmanipulation, um dabei zu helfen. Gute Sache, danke Chris!
Vielen Dank für diesen Überblick! Ich habe eine ganze Reihe von Dingen gemacht, die in Kunden-Websites eingefügt werden, und ich beginne, sie alle auf async zu aktualisieren, dank dieses Artikels!
„Es gibt zwei Gründe dafür:“
Rohr. Grammatik. Miau.
Eine Sache, die man beachten sollte, ist, dass Modernizr tatsächlich das YepNope-Skriptlade-Tool enthält, was großartig ist, da ich bereits Modernizr für die HTML5-Fallbacks und Feature-Erkennungen lade.
Hallo Chris,
Vielen Dank für das Teilen.
jQuery hat auch die getScript-Funktion, eine Abkürzung für Ihr .ajax-Beispiel. http://api.jquery.com/jQuery.getScript/
Ich hasse es zu pingelig zu sein. Ihr Beispiel Umgang mit CMS oben
Entfernen Sie das Semikolon von foo:bar;
danke
Sie können auch Callbacks wie die Google Maps API verwenden
etwas nervig, aber der klassische Weg braucht ein schließendes Tag
danke
Chris, eine Sache, die für die jQuery-Benutzer erwähnenswert ist, ist, dass die Verwendung von async JS sich auf
$(window).load(function(){});auswirkt, was üblich ist, um DOM-Manipulationen auszulösen, sobald alle Bilder auf der Seite geladen sind. Je mehr Drittanbieter-Async-Aufrufe erfolgen, desto größer wird die Notwendigkeit eines Timeouts oder einer Fehlerbehandlung beim window.load-Ereignis.Hallo Chris,
Ich denke, es gibt Raum für Verbesserungen in Ihrem neuen WuFoo async-Snippet, insbesondere bei der Code-Größe.
Ich habe einige Teile Ihres Snippets neu geschrieben und dabei die gleiche Funktionalität beibehalten.
Schauen Sie sich diesen Gist an: https://gist.github.com/2011869
Ich hoffe, es gefällt Ihnen ;)
Wissen Sie, ob es möglich ist, Google AdSense asynchron zu laden? Ich habe letzte Woche ein paar Dinge mit window.onload versucht, aber es hat überhaupt nicht funktioniert.
Ich denke, alle h5bp-Kinder da draußen müssen sich keine Sorgen um blockierende Skripte machen, da sie wahrscheinlich Modernizr in ihrem HTML-Head haben und dadurch Zugriff auf die großartige
Modernizr.load-Methode haben.Dies macht eigentlich alle anderen Skript-Lader überflüssig. Außer require.js. Aber das ist kein einfacher Skript-Lader, sondern ein Ansatz zur Modularisierung von JavaScript und zur Abhängigkeitsverwaltung. Man braucht require.js nicht nur, um ein oder zwei externe Skripte asynchron zu laden.
Vielen Dank für das Teilen, wie üblich wird es sehr geschätzt.
Viele Grüße,
Chris
Hallo Chris,
Der jQuery-Schnipsel ist ziemlich raffiniert!
Aber Sie möchten vielleicht
cache: truehinzufügen, da jQuery standardmäßig das Caching fürdataType: scriptdurch Anhänge eines Query-Strings vermeidet.In den meisten Fällen würde dies ein Performance-Problem auf Client-/Server-Seite verursachen, daher möchten Sie vielleicht einen Hinweis für diejenigen jQuery-Benutzer hinzufügen, die die Dokumentation nicht täglich lesen ;)
Wir verwenden head.js seit einigen Projekten erfolgreich. – Es ist vorhersehbar und leicht verständlich.
Für jQuery sollten Sie die Funktion
$.getScript()verwenden. Sie macht den Code viel lesbarer in Bezug auf das, was tatsächlich passiert.Gute Übersicht, Chris.
Für das jQuery-basierte Beispiel ist es wahrscheinlich eine gute Idee, das Caching zu aktivieren, indem Sie
'cache': trueangeben, wie hier: https://gist.github.com/1197140 Andernfalls wird ein zeitgestempelter Parameter an die Anforderungs-URL angehängt, um sicherzustellen, dass der Browser das Skript jedes Mal herunterlädt, wenn es angefordert wird – was Sie in diesem Fall wahrscheinlich nicht möchten.Es ist erwähnenswert, dass
jQuery.getScript()ebenfalls standardmäßig cachebustet. Der einzige Weg, dies zu überschreiben (abgesehen von der Verwendung vonjQuery.ajax()und der Aktivierung der Optioncache), ist die globale Einstellung der Eigenschaftcache.Es gibt ein Skript, das es Ihnen ermöglicht, das document.write-Problem zu umgehen. Es heißt Ghostwriter: http://digital-fulcrum.com/solutions/ghostwriter-complete-control/
Externe Ressourcen asynchron zu laden ist ein MUSS!
Wir laden in einigen unserer Projekte sogar CSS asynchron...
Offensichtlich laden wir Stylesheets asynchron, die erst nach einer „Aktion“ unserer Benutzer benötigt werden oder wenn das CSS einige optionale Regeln (z. B. CodeMirror-CSS) für HTML-Elemente enthält.
Wir verwenden die „Standardmethode“, um asynchrone JS/CSS-Dateien zu laden, indem wir ein Skript-/Link-Element an den Kopf anhängen.
Übrigens, danke für diesen Artikel!
Wer denkt ernsthaft noch an IE6?!? Kommen Sie darüber hinweg.
Warum die Skripte nicht einfach am Ende des Body-Tags platzieren? Es sei denn, Ihre Benutzer laden Unmengen an Skriptdateien (1 MB+), die Seite ist sowieso fast sofort reaktionsfähig und die Skripte wurden geladen, bevor die Benutzer etwas versuchen (da der DOM und die Stile bereits geladen wurden). Sie lädt sogar schneller, da der Benutzer keine zusätzliche HTTP-Anfrage für eine Datei warten muss. Deshalb zerteilen wir Bilder nicht mehr :)
Ich schätze, das macht Sinn für mehrere, größere, weniger wichtige Dateien, wenn sie die Website-Performance merklich beeinträchtigen. Es erscheint mir nur seltsam, einen Benutzer warten zu lassen, bis ein asynchroner Lade-Manager geladen hat UND dann zusätzlich warten zu lassen, bis ein Skript asynchron geladen wurde.
Das jQuery-Beispiel ist leicht fehlerhaft, hier ist die kleine Änderung
Ich habe vor ein paar Wochen etwas Ähnliches gemacht. Ich mag es, den Callback-Teil im „Facebook“-Stil zu gestalten, auch zu prüfen, ob das Skript bereits geladen wurde (aber dieser Teil kann natürlich entfernt werden)
Den Rest können Sie auf GitHub prüfen
https://github.com/keriati/async-js
Tolle Zusammenfassung, Chris!
Für soziale Schaltflächen wie „Tweet“ und „Like“ könnte Ihnen Socialite.js http://socialitejs.com gefallen – es ist ein spezialisierter Skript-Lader, an dem ich für soziale Netzwerke arbeite, der das Laden unbegrenzt verzögern kann.
Danke für den Artikel.
Ich bin nach einem Tipp von Google Page Speed Online auf Ihren Beitrag gestoßen, der mir empfohlen hat, die Skripte asynchron zu laden.
Sie könnten auch die Methode
<script id="blah">+getElementById('blah').addEventListener('load')verwenden, um etwas nach der Ausführung des asynchronen Skripts zu tun.Bibliotheken wie RequireJS und so weiter verwalten paralleles Laden und finale Callback-Ereignisse, um komplexen verschachtelten Code zu vermeiden.
Das ist gut!
Aber wir können JS nicht erkennen, ob es geladen ist oder nicht in der Google Maps API, um unsere Callback-Funktion auszuführen.
Google lädt immer mehr als eine JavaScript-Datei in seinem API-Code...
Schauen wir uns https://maps.googleapis.com/maps/api/js?sensor=false an
Danke Chris!
Haben Sie Socialite.js https://github.com/tmort/Socialite ausprobiert – auch nett für soziale Netzwerke
Ich denke, einer der interessantesten asynchronen Skript-Lader, über den niemand zu sprechen scheint, ist defer.js. Im Gegensatz zu jeder anderen Lösung kann es sich selbst einfach asynchron laden. Das bedeutet null blockierende Skripte. Ihr gesamter „muss ausgeführt werden“-Code kann inline vor CSS stehen, wie es jetzt empfohlen wird.
Ich bevorzuge die Verwendung eines Plugins für alle selbst gehosteten WordPress-Benutzer. Der Plugin-Name ist: Async JS and CSS. Derzeit verwende ich dies und Google Page Speed zeigt keine blockierenden JavaScript- und CSS-Dateien im Renderblocker an. Funktioniert für mich großartig....