Warum nicht mal den Client quälen?

Das ist eine Frage, die sich wohl jeder Dienstleister des öfteren stellt, allerdings spreche ich hier nur vom Clientrechner.

Flash bietet ja spätestens seit Version 9 diverse Möglichkeiten, komplexere Operationen vom Server auf den Client auszulagern, wie es vorher eigentlich nur mit Java möglich war, z.B. das erzeugen von PDF-Dateien mittels AlivePDF. Der Nachteil fällt allerdings spätestens dann auf, wenn man etwas komplexeres als eine kleine Rechnung als PDF erzeugen möchte, in meinem Fall geht es hier um ein PDF im DIN A0-Format mit ca. 4000 geometischen Vektorobjekten, über 1000 Textobjekte und ein paar hochauflösende Grafiken. Wenn man die Daten für die PDF-Generierung als Object oder Array gefüllt mit Objekten vorhält bietet sich eine verschachtelte Schleife an, um das PDF entsprechend zu erzeugen.

Das Problem ist jetzt die Laufzeit dieser Schleife. Wie der geneigte Flashomat sicherlich weiss neigt das Plugin dazu, sich sehr zurückhaltend zu benehmen, während eine Schleife läuft. Im Optimalfall bekommt man davon nicht viel mit, im schlimmsten Fall aktualisiert nicht einmal mehr die Anzeige während des Vorgangs, was für den Benutzer vor dem Bildschirm am Schluß mit hoher Wahrscheinlichkeit wenig erfreulich aussieht, so dass wir ihn zum einen über den Fortschritt informieren wollen, zum Anderen wäre es natürlich schön, wenn auch auf Rechenknechten, die schon während des ersten Weltkriegs im Einsatz waren und entsprechend unter CPU-Schwachbrüstigkeit leiden, nicht das leidige Fenster erscheint, dass vor einer vermeintlichen Endlosschleife warnt.

Zumindest um den Benutzer auf dem Laufenden zu halten gibt es eine einfache Lösung – ExternalInterface. Während das Flash-Plugin zwar so eingefrohren scheint wie ein Löwe in der Arktis und daher nicht einmal mehr die Anzeige aktualisieren kann während die Schleife läuft – ExternalInterface klappt noch. Also schnell irgendwo in der Schleife (am Besten da, wo es Sinn macht) ein ExternalInterface eingebaut, dass eine JS-Funkion aufruft, die wiederum den Status ausserhalb des Flashfilms – z.B. innerhalb eines Layers, der über dem SWF liegt, aktualisiert – und der User weiss Bescheid.

Freilich löst das nicht das Problem der Plugin-Auslastung. Hier braucht man ein wenig “Mut zur Hässlichkeit” am Code, dann kriegt man allerdings auch das Problem gelöst. Erster Instinkt dürfte sein, die erste Ebene der Schleife aufzudröseln, alles untergeordnete in eine Funktion auszulagern, die man dann jeweils zum Ende der Schleife rekursiv aufruft, bis man Fertig ist. Vor oder nach der Schleifen innerhalb der Funktion müsste sich ja die Anzeige aktualisieren lassen, da man sich nicht mehr in einer Schleife befindet. Falsch. Leider. Die Zeit bis zum Beginn der nächsten Schleife reicht hier nicht aus, um die Anzeige zu aktulisieren, die Änderung findet also ärgerlicherweise nicht statt. Ich nehme an, das ist ein Erbe des zeitleistenbasierten Aufbaus, der ja immer noch existiert und zahlreichen Werbemittelschraubern das Einkommen sichert – die Zeit reicht nicht aus, einen neuen Frame auszubauen, das wird von der nächsten Schleife einfach unterbunden.

Es hilft: Der Timer. Nach der Aktualisierung gönnt man dem Plugin per Timer-Instanz eine kleine Pause von z.B. 50 ms. Der Benutzer vor dem Bildschirm bekommt das quasi nicht mit, es reicht aber aus aus, damit das Plugin durchatmen kann, gemütlich den nächsten Frame rendert und den Benutzer so auf den aktuellen Stand bringt. Auch die Gefahr der “Skript-Timeout”-Warnung wird damit reduziert.

Eigentlich wollte ich jetzt noch ein kleines Codebeispiel bringen, aber ehrlich gesagt werde ich im Krieg auf XboxLive erwartet. Eventuell reiche ich das ein ander mal nach. :)

Veröffentlicht am 22. Januar 2010 um 9:59 pm von admin · Permalink
In: Code

Kommentieren