Artikel-Schlagworte: „Javascript“

AJAX-Requst bei JQuery abbrechen

Donnerstag, 13. August 2009

Manchmal möchte man einen AJAX-Request abbrechen. Gründe dafür können beispielweise neu eingetretene Ereignisse oder ein Wegnavigieren des Users sein.

Eine sehr gute Library um die Nutzung von AJAX browserunabhängig zu machen ist JQuery. Schaut man sich die Dokumentation von JQuery an, wird man jedoch vergeblich nach einer Methode zum beenden eines Requests suchen. Der Grund dafür ist einfach: Die Anfragen können parallel also asynchron ablaufen – das ist schließlich der Grund dafür AJAX einzusetzen. Damit erhält aber jeder Request einen eigenen Kontext und kann deshalb nicht mit einer einfachen Methode der JQuery-API beendet werden.

Die Lösung liegt im “Aufbewahren” des Request Objects. Ein typischer Code-Abschnitt für einen AJAX-Request sieht so aus:

 // Parameter aufbereiten
 var sendData = {
    a: this.a,
    b: this.b,
 };

 // Daten laden
 cbRef = this;   
 this.xhr = $.ajax({
    url: 'http://www.....',
    dataType: 'json',
    type: "POST",
    data: sendData,
    success: function(data) {
       cbRef.myCallback(data);
    }
 });

Es werden also die Parameter für den Request zusammengestellt und an die angegebene URL gepostet. Die ajax-Methode von JQuery gibt dabei das XmlHttpRequest-Object das für die Anfrage verwendet wird zurück. Dieses Objekt enthält den Kontext, also den Bezug zur Anfrage.

Wenn wir diese spezielle Anfrage also beenden möchten, können wir einfach die abort()-Methode aufrufen:

this.xhr.abort();

Wenn viele Anfragen gleichzeitig gestartet werden sollen, müssen natürlich entsprechend mehr Variablen zur temporären Speicherung der Requests vorgesehen werden.

Javascript-Performance und setInterval()

Freitag, 3. Juli 2009

Viele Javascripte benötigen eine Taktung um ihre Aktionen wie gewünscht auszuführen. Ein Menü zum Beispiel soll sich kurz nachdem der Mauszeiger es verlassen hat wieder schliessen, ein Fortschrittsbalken soll sich regelmäßig aktualisieren und CSS-Annimationen sollen auch in einer bestimmten Geschwindigkeit ausgeführt werden.

Üblicherweise die die Funktion setInterval() dazu, eine weitere Funktion in einem bestimmten Interval aufzurufen. Dazu muss nur eine Funktion und das gewünschte Interval übergeben werden:

setInterval(meineFunktion, 250);

Nach dem Aufruf wird die Funktion meineFunktion alle 250ms vom Browser automatisch aufgerufen. Eigentlich eine einfache Sache, denn für einen halbwegs aktuellen Rechner sollte es keine besondere Herausforderung sein, vier mal pro Sekunde eine Funktion aufzurufen.

Während eines größeren Entwicklungsprojekts musste ich regelmäßig ein Update in einem Objekt auslösen und habe dies genau wie eben beschrieben programmiert. Als Interval habe ich bei meinen ersten Versuchen 100ms eingestellt. Dabei fühlte sich mein Firefox subjektiv “beschäftigt” an. Es entstand zwar keine Blockierung, aber es fühlte sich einfach langsamer an.

Der Task-Manager bestätigte diesen Eindruck dann auch sogleich:

Auslastung bei 100ms

Auslastung bei 100ms

Also ca. 5% Auslastung. Nicht wirklich viel, aber ich hatte ja nachgeschaut, weil es subjektiv langsamer wurde. Was passiert nun, wenn man den Intervall verkürzt? Als nächstes wurde der Timer auf ein 50ms Interval gesetzt und wieder die Auslastung geprüft (nach einigen Sekunden pendelt sich der angezeigte Wert ein):

und bei 50ms...

und bei 50ms...

Nun lag die Auslastung bei ca 10%. Auf einem etwas älteren Rechner kann eine das die Benutzung einer Webanwendung schon ziemlich vermiesen. Obwohl das Ergebnis eigentlich schon zu erwarten war, musste natürlich auch noch das kürzest mögliche Interval getestet werden: 1ms.

Wahnsinn...

Wahnsinn...

Damit ist es nun endgültig mit der Performance vorbei. Dabei war das Hinken des Firefox förmlich zu ahnen, denn eigentlich sollte sich der zu Debugzwecken eingebaute Zähler bei einem Intervall von 1ms ja in jeder Sekunde um 1000 erhöhen. Nach ca. 10 Sekunden zeigte er aber nur einen Zählerstand um die 7000 an.

Schlußfolgerungen

Zunächst gelten diese Ergebnisse nur für den Firefox 3.0.11 mit Firebug und Webdeveloper-Toolbar. Trotzdem ist die Auswirkung einer scheinbar harmlosen Funktion nicht zu unterschätzen. Man sollte also jederzeit nach dem “richtigen” Interval fragen, sonst wird aus dem scheinbaren Vorteil einer fluffigen Aktualisierung schnell ein Nachteil.

Wir haben für uns folgende Punkte herausgearbeitet:

  • Was ist das längstmögliche Interval ohne Verlust an Look&Feel?
  • Müssen die Timer immer durchlaufen oder können sie nach der Aktion gestoppt werden?
  • Testen, testen, testen. Jeder Browser verhält sich anders.