Mehr Speed durch parallele AJAX-Requests

Verfasst am: 20. 07. 2011 [18:31]
Ultima
Dabei seit: 09.07.2010
Themenersteller

759 Beiträge
Beitrag hilfreich?

Hallo Forum,

mal noch etwas zu diesem Thema:
http://blog.seitenreport.de/artikel/2011/04/05/howto-mehr-speed-durch-parallele-ajax-requests/


Hier ist noch eine kleine Lösung für dieses Thema verpackt in einem Objekt.
Der Vorteil dieser Variante ist das man selber bestimmen kann wie viele Anfragen gleichzeitig gesendet werden sollen (der FF macht maximal 6 je Domain) und es wird zwischen Post und Get Unterschieden. Wenn zu viele Anfragen auf einmal kommen, werden diese in eine Warteschlange gestellt.


Hier mal das Objekt:
JAVASCRIPT
<script type="text/javascript">
var request={
	channels:[],
	channelsize:5,
	querys:[],
	init:function(){
		for(var i=0;i<this.channelsize;i++)this.channels[i]=null;
	},
	/**
	 * send a XMLHttpRequest
	 *
	 * @param uri	The uri of the ressource.
	 * @param post	Post datafield.
	 * @param cb	Callbackfunction for the response.
	 */
	send:function(uri,post,cb){
		this.querys.push({'uri':uri,'post':post,'cb':cb});
		this._run();
	},
	_run:function(){
		if(this.querys.length==0)return;
		for(var i=0;i<this.channelsize;i++){
			if (this.channels[i]===null) {
				var job=this.querys.pop();
				this.channels[i] = new XMLHttpRequest();
				this.channels[i].callback=job.cb;
				this.channels[i].id=i;
				this.channels[i].open((job.post)?'POST':'GET', job.uri, true);
				if(job.post)this.channels[i].setRequestHeader('Content-type','application/x-www-form-urlencoded;Charset=utf-8');
				this.channels[i].onreadystatechange=function(){
					if(this.readyState==4){
						if (this.status==200)eval(this.callback+'(this.responseText)');
						request._clearChannel(this.id);
					}
				}
				this.channels[i].send(job.post);
				break;
			}
		}
	},
	_clearChannel:function(id){this.channels[id]=null;this._run()}
}
request.init();
</script>


Und so werden die Anfragen gesendet:
JAVASCRIPT
<script type="text/javascript">
// mit Post Daten
request.send('example.php','foo=bar&bar=foo','callback');
 
// mit Get Daten
request.send('example.php?foo=bar&bar=foo',null,'callback');
 
// oder beides
request.send('example.php?get=foo', 'post=bar','callback');
</script>


Und so könnte die Callback Funktion aussehen:
JAVASCRIPT
<script type="text/javascript">
function callback(responseText) {
	// Reponse verarbeiten
}
</script>



So mich würde eure Meinung dazu interessieren und was ich noch verbessern könnte. (Die Unterstützung von älteren Browsern habe ich absichtlich ignoriert.)


Schöne Grüße
Thomas

[Dieser Beitrag wurde 2mal bearbeitet, zuletzt am 20.07.2011 um 18:37.]

 
Verfasst am: 20. 07. 2011 [19:21]
romacron
Dabei seit: 01.11.2009

1143 Beiträge
Beitrag hilfreich?

Hallo Thomas,

ich denke der Lösungsansatz könnte anders aussehen.
Vorweg, mehrere gleichzeitige Anfragen(diese werden ohnehin aufgereiht)machen wenig Sinn bzw könnten sinnvoller ausgeführt werden.

1. es braucht nur einen einzigen Request.
in diesen Packt man alle Anfragen bzw.Parameter hinein.
Serverseitig nimmt man diese Anfrage auseinander und zerlegt sie in die einzelnen Aufgaben.
Als Beispiel: 2 Formulare auf der Webseite. Die übermittle ich mit einem Request, verarbeitet werden diese ohnehin separat auf dem Server. Die Response ist dann natürlich auch nur eine. Die "entpackt" sich dann im Clientbrowser wieder an die richtigen Stellen.

Fazit: alles in ein Request/Response schneller gehts nicht.
 
Verfasst am: 20. 07. 2011 [20:19]
UFOMelkor
Dabei seit: 20.10.2009

348 Beiträge
Beitrag hilfreich?

Hallo Ultima,

ich denke dein Objekt könnte durch die Nutzung von Closures profitieren:
Hier mal eine Version die Closure nutzt:
JAVASCRIPT
<script type="text/javascript">
var sendRequest=(function(){
    var channels    = [],
        channelsize = 5,
        querys      = [],
        i;
 
    // init
    for (i = 0; i < channelsize; i += 1) {
        channels[i] = null;
    }
 
    var run = function() {
        // Inhalt zu ergängen
    };
 
    var clearChannel = function(id) {
        // Inhalt zu ergänzen
    };
 
    /**
    * send a XMLHttpRequest
    *
    * @param uri	The uri of the ressource.
    * @param post	Post datafield.
    * @param cb	Callbackfunction for the response.
    */
    var send = function(uri,post,cb){
        querys.push({'uri':uri,'post':post,'cb':cb});
        run();
    };
    return send;
})();
 
 
// Aufruf
sendRequest('exampe.php', 'foo=bar&bar=foo', callback);
</script>


Beim Aufrufen übrigens bitte keinen String, sondern die Funktion selbst übergeben. Das gibt nochmal einen Performance-Schub wink.gif



 
Verfasst am: 20. 07. 2011 [21:14]
Ultima
Dabei seit: 09.07.2010
Themenersteller

759 Beiträge
Beitrag hilfreich?

Danke für eure Antworten. :)

"romacron" schrieb:
Fazit: alles in ein Request/Response schneller gehts nicht.

Da gebe ich dir recht, allerdings ist das bei meinem Vorhaben so nicht (immer) möglich. Da man nicht sagen kann welche Daten der User anfordert und wann. Und alles auf einmal zu laden wäre in diesem Fall zu viel, und man kann auch nicht wissen ob es gebraucht wird. Daher diese Lösung.

"UFOMelkor" schrieb:
Beim Aufrufen übrigens bitte keinen String, sondern die Funktion selbst übergeben. Das gibt nochmal einen Performance-Schub.
Das ist auch gut, aber werden die Funktionen dann nicht zu anonymen Funktionen? Das würde mir Callbackfunktionen die Methoden eines anderen Objektes sind Probleme bereiten da der Zeiger 'this' dann nicht mehr existiert.

Oder sehe das falsch?


 
Verfasst am: 21. 07. 2011 [06:45]
romacron
Dabei seit: 01.11.2009

1143 Beiträge
Beitrag hilfreich?

..ich verstehe wink.gif

zu this und callbacks. Hast du prototype-ing einmal in Betracht gezogen?
zwar sind es 20 Zeilen Code mehr, man verfügt dann aber über den Luxus einer "instance"
 
Verfasst am: 21. 07. 2011 [09:35]
UFOMelkor
Dabei seit: 20.10.2009

348 Beiträge
Beitrag hilfreich?

"Ultima" schrieb:
Das ist auch gut, aber werden die Funktionen dann nicht zu anonymen Funktionen? Das würde mir Callbackfunktionen die Methoden eines anderen Objektes sind Probleme bereiten da der Zeiger 'this' dann nicht mehr existiert.

Oder sehe das falsch?


Jein:

JAVASCRIPT
<script type="text/javascript">
var foo = {
    bar: "World",
    baz: function(){
        console.log("Hello ");
        console.log(this.bar);
    }
};
 
// einmal ohne Callback
foo.baz();
 
// und einmal mit
window.setTimeout(foo.baz, 0);
</script>


[CODE]
Hello
World
Hello
[/CODE]

Gibt also tatsächlich ein Problem mit this und callbacks. Das lässt sich aber ganz einfach umgehen:

JAVASCRIPT
<script type="text/javascript">
var foo = {
    bar: "World",
    baz: function(){
        console.log("Hello ");
        console.log(this.bar);
    }
};
 
// einmal ohne Callback
foo.baz();
 
// und einmal mit
window.setTimeout(function(){foo.baz();}, 0);
</script>


[CODE]
Hello
World
Hello
World
[/CODE]

Auf Strings kann man also getrost verzichten :)

 
Verfasst am: 21. 07. 2011 [10:04]
Ultima
Dabei seit: 09.07.2010
Themenersteller

759 Beiträge
Beitrag hilfreich?

"romacron" schrieb:
Hast du prototype-ing einmal in Betracht gezogen?

Ja, das Prototyping nutze ich um eine Vererbung/Spezialisierung zu simulieren. Allerdings nicht in diesem Objekt. JavaScript unterstützt ja leider (noch) kein Objekt orientiertes programmieren icon_frown.gif es ist ja nur Objekt basierend.


Danke für die Tipps.

[Dieser Beitrag wurde 1mal bearbeitet, zuletzt am 21.07.2011 um 10:05.]

 




Du bist nicht eingeloggt. Bitte beachte, dass Du eingeloggt sein musst, um Themen zu erstellen oder auf Beiträge zu antworten.

RSS Feed abonnieren

Werde in Echtzeit über neue Foren-Beiträge informiert:



0 Mitglieder waren innerhalb der letzten 15 Minuten online (24 heute gesamt):
[keine]

Administratoren und Moderatoren:
[keine]

Seitenreport hat 18136 registrierte Mitglieder, 3002 Themen und 29106 Beiträge.
Der aktuelle Mitgliederzuwachs liegt bei durchschnittlich 12 bestätigten Neuregistrierungen pro Tag.
Pro Tag werden im Seitenreport Forum durchschnittlich 1 neues Thema und 8 Beiträge erstellt.
Die Durchschnittszahlen berechnen sich aus den letzten 7 Tagen.

Mehrfach empfohlen

Seitenreport ist einer der bekanntesten SEO und Website Analyse Dienste im deutschsprachigen Raum und wurde u.a. schon empfohlen:
von Mr. Wong im Wong Letter
vom Leserservice der Deutschen Post
vom Technik Blog SiN
und vielen anderen

Partnerprogramm

12% Lifetime Provision auf alle Buchungen von Dir geworbener Mitglieder sowie 0,50 € für jede Registrierung. Eines der besten deutschen Partnerprogramme laut den appCharts von 100partnerprogramme.de. Nimm jetzt teil am Seitenreport Partnerprogramm und verdiene gutes Geld dabei!

* = Partnerlinks