Das nicht blockierende Laden von Javascript spielt eine große Rolle bei der Optimierung der Seitenleistung. Dadurch kann das Blockieren von JS beim Laden der Seite effektiv reduziert werden. Insbesondere bei einigen Werbe-JS-Dateien kann es zu einem Engpass für die Ladegeschwindigkeit Ihrer Seite kommen. Hochleistungs-Javascript fordert uns, Studenten, auf, JS ohne Blockierung zu laden, um die Geschwindigkeit Ihrer Webseite zu verbessern.
Dann erscheint ein Code.
(function() { var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = 'http://yourdomain.com/script.js'; var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x); })();
Jeder, der das Buch gelesen hat, kennt die Vorteile des nicht blockierenden Ladens. Wenn solche nicht blockierenden Skripte auf gewöhnliche JS-Werbung stoßen, treten Probleme beim Schreiben auf erscheint im HTML, es werden jedoch keine Anzeigen angezeigt.
Nani? Der HTML-Code wird nach der Veröffentlichung nicht auf der Seite gerendert?
Schauen Sie sich zuerst den Werbe-JS-Code an
Der Code ist recht einfach, nur ein document.write, der HTML-Code ausgibt (ich glaube, dass die Anzeigen vieler Werbetreibender so sind). Was ist das Problem, wenn auf der Seite keine Anzeigen angezeigt werden? Das Problem liegt in diesem document.write. Warum? Werfen wir zunächst einen Blick auf w3schools, um zu sehen, wie nützlich die Definition von document.write ist.
Definition und Verwendung
Die Methode write() schreibt HTML-Ausdrücke oder JavaScript-Code in das Dokument.
Es können mehrere Parameter (exp1, exp2, exp3,...) aufgelistet werden, die der Reihe nach an das Dokument angehängt werden.
Methode:
Eine besteht darin, mit dieser Methode HTML im Dokument auszugeben, und die andere darin, ein neues Dokument in einem anderen Fenster oder Frame als dem Fenster zu generieren, in dem diese Methode aufgerufen wird. Im zweiten Fall verwenden Sie unbedingt die Methode close(), um das Dokument zu schließen.
Aber das Prinzip besteht darin, dass es während des Seitenfluss-Eingabevorgangs ausgeführt wird. Sobald die Seite geladen ist, ruft ein erneuter Aufruf von document.write() implizit document.open() auf, um das aktuelle Dokument zu löschen und ein neues Dokument zu starten. Das heißt, wenn wir document.write nach dem Laden des HTML erneut verwenden, wird das zuvor generierte HTML gelöscht und der von document.write ausgegebene Inhalt angezeigt.
Wenn in unserem Beispiel document.write nach dem Laden der Seite in HTML ausgegeben wird, wird es nicht ausgeführt. Nachdem wir nun das Problem und das Prinzip kennen, wie können wir dieses Problem lösen?
Bei der asynchronen Verwendung von Ajax sind die Zeilen unterschiedlich. Unter verschiedenen Domänennamen gibt es domänenübergreifende Probleme und wir können die Ausgabe ihrer Codes nicht steuern. In diesem Fall haben wir über eine Möglichkeit nachgedacht, document.write neu zu schreiben und document.write dann wieder neu zu schreiben, nachdem die js-Datei geladen wurde. Schauen Sie sich den Code an.
Die erste Version lädt js-Anzeigen ohne Blockierung:
function LoadADScript(url, container, callback){ this.dw = document.write; this.url = url; this.containerObj = (typeof container == 'string'?document.getElementById(container):container); this.callback = callback || function(){}; } LoadADScript.prototype = { startLoad: function(){ var script = document.createElement('script'), _this = this; if(script.readyState){ //IE script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; _this.finished(); } }; }else{ //Other script.onload = function(){ _this.finished(); }; } document.write = function(ad){ var html = _this.containerObj.innerHTML; _this.containerObj.innerHTML = html + ad; } script.src = _this.url; script.type = 'text/javascript'; document.getElementsByTagName('head')[0].appendChild(script); }, finished: function(){ document.write = this.dw; this.callback.apply(); } };
Seitenaufrufcode:
var loadScript = new LoadADScript('ad.js','msat-adwrap',function(){ console.log('msat-adwrap'); }); loadScript.startLoad(); var loadScript = new LoadADScript('ad2.js','msat-adwrap',function(){ console.log('msat-adwrap2'); }); loadScript.startLoad(); var loadScript = new LoadADScript('ad3.js','msat-adwrap',function(){ console.log('msat-adwrap3'); }); loadScript.startLoad();
JS-Code für Werbung
//ad.js document.write('<img src="http://images.cnblogs.com/logo_small.gif" alt="Logo">'); //ad2.js document.write('<img src="http://www.baidu.com/img/baidu_sylogo1.gif" width="270" height="129" usemap="#mp">'); //ad3.js document.write('<img alt="Google" height="95" id="hplogo" src="http://www.google.com/images/srpr/logo3w.png" width="275">');
Das Problem bei der ersten Version besteht darin, dass beim Aufruf mehrerer Dateien einige Probleme auftreten:
1. Aufgrund der unterschiedlichen Ladegeschwindigkeiten von Dateien werden einige möglicherweise zuerst und andere später geladen, was ungeordnet ist und oft in Ordnung ist. Beispielsweise müssen wir zuerst die erste Bildschirmanzeige laden.
2. Ich denke, dass einige Anzeigen im Voraus einige Parameter festlegen müssen, wie zum Beispiel Google Adsense
Um diese beiden Probleme zu lösen, haben wir es weiter in die endgültige nicht blockierende Lade-JS-Version geändert.
HTML-Seitencode:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>new_file</title> <script type="text/javascript" src="loadscript.js"></script> </head> <body> <div id = "msat-adwrap"></div> <div id = "msat-adwrap2"></div> <script type="text/javascript"> loadScript.add({ url:'ad.js', container: 'msat-adwrap', callback:function(){ console.log('msat-adwrap'); } }).add({ url:'ad2.js', container: 'msat-adwrap2', callback:function(){ console.log('msat-adwrap2'); } }).add({//google adsense url:'http://pagead2.googlesyndication.com/pagead/show_ads.js', container: 'msat-adwrap', init: function(){ google_ad_client = "ca-pub-2152294856721899"; /* 250x250 rich */ google_ad_slot = "3929903770"; google_ad_width = 250; google_ad_height = 250; }, callback:function(){ console.log('msat-adwrap3'); } }).execute(); </script> </body> </html>
loadscript.js-Quellcode
/** * 无阻塞加载广告 * @author Arain.Yu */ var loadScript = ( function() { var adQueue = [], dw = document.write; //缓存js自身的document.write function LoadADScript(url, container, init, callback) { this.url = url; this.containerObj = ( typeof container == 'string' ? document.getElementById(container) : container); this.init = init || function() { }; this.callback = callback || function() { }; } LoadADScript.prototype = { startLoad : function() { var script = document.createElement('script'), _this = this; _this.init.apply(); if(script.readyState) {//IE script.onreadystatechange = function() { if(script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; _this.startNext(); } }; } else {//Other script.onload = function() { _this.startNext(); }; } //重写document.write document.write = function(ad) { var html = _this.containerObj.innerHTML; _this.containerObj.innerHTML = html + ad; } script.src = _this.url; script.type = 'text/javascript'; document.getElementsByTagName('head')[0].appendChild(script); }, finished : function() { //还原document.write document.write = this.dw; }, startNext : function() { adQueue.shift(); this.callback.apply(); if(adQueue.length > 0) { adQueue[0].startLoad(); } else { this.finished(); } } }; return { add : function(adObj) { if(!adObj) return; adQueue.push(new LoadADScript(adObj.url, adObj.container, adObj.init, adObj.callback)); return this; }, execute : function() { if(adQueue.length > 0) { adQueue[0].startLoad(); } } }; }());