gelöschter Benutzer

Mehr Speed durch parallele AJAX-Requests

am 20.07.2011, 18:31 Uhr eröffnete folgenden Thread
AJAX & JavaScript (JS)    2594 mal gelesen    6 Antwort(en).

Hallo Forum,

mal noch etwas zu diesem Thema:

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:
[JS]<script>
var request={
channels:[],
channelsize:5,
querys:[],
init:function(){
for(var i=0;i<this.channelsize;i++)this.channels[i]=null; <br /> },
/**
* 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++){ <br /> 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>[/JS]

Und so werden die Anfragen gesendet:
[JS]<script>
// 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>[/JS]

Und so könnte die Callback Funktion aussehen:
[JS]<script>
function callback(responseText) {
// Reponse verarbeiten
}
</script>[/JS]


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


romacron
JDev Xer
Content Gott (1224 Beiträge)
am 20.07.2011, 19:21 Uhr schrieb romacron

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.


UFOMelkor
Avatar UFOMelkor
Student
Content Meister (350 Beiträge)
am 20.07.2011, 20:19 Uhr schrieb UFOMelkor

Hallo Ultima,

ich denke dein Objekt könnte durch die Nutzung von Closures profitieren:
Hier mal eine Version die Closure nutzt:
[JS]<script>
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>[/JS]

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


Naturkosmetik in Bochum

Steppenhahn Ultramarathon-Community


gelöschter Benutzer
am 20.07.2011, 21:14 Uhr schrieb

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?


romacron
JDev Xer
Content Gott (1224 Beiträge)
am 21.07.2011, 06:45 Uhr schrieb romacron

..ich verstehe

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"


UFOMelkor
Avatar UFOMelkor
Student
Content Meister (350 Beiträge)
am 21.07.2011, 09:35 Uhr schrieb UFOMelkor

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:

[JS]<script>
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>[/JS]

[CODE]
Hello
World
Hello
[/CODE]

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

[JS]<script>
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>[/JS]

[CODE]
Hello
World
Hello
World
[/CODE]

Auf Strings kann man also getrost verzichten


Naturkosmetik in Bochum

Steppenhahn Ultramarathon-Community


gelöschter Benutzer
am 21.07.2011, 10:04 Uhr schrieb

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 es ist ja nur Objekt basierend.


Danke für die Tipps.


  • 1


« zurück zu: AJAX & JavaScript (JS)

Das Seitenreport Forum hat aktuell 5273 Themen und 36107 Beiträge.
Insgesamt sind 48345 Mitglieder registriert.