jogisarge: AJAX - Content in Steps laden

Hallo zusammen,

ich habe ein PHP-JS Konstrukt.
Per Klick auf einen Button rufe ich eine JS-Funktion auf und diese macht einen AJAX-Request an ein PHP-Script welches eine "Table" zurückliefert.
Diese "Table" schreibe ich per JS in ein DIV.

Soweit passt das.
Da die Ladezeit aber sehr lange dauert, weil der Inhalt der "Table" über einen Webservice geladen wird, benötige ich eine andere Lösung.

Mein Gedanke wäre nun, die Zeilen der Tabelle in Steps zurückzuliefern, aber ich hab momentan keine Idee, wie das gehen soll.
Ich müsste ja den AJAX-Request in einer Schleife laufen lassen, biss PHP das Ende zurückmeldet, oder bin ich da auf dem Holzweg ?

LG jogi

  1. Per Klick auf einen Button rufe ich eine JS-Funktion auf und diese macht einen AJAX-Request an ein PHP-Script welches eine "Table" zurückliefert.
    Diese "Table" schreibe ich per JS in ein DIV.

    Da die Ladezeit aber sehr lange dauert, weil der Inhalt der "Table" über einen Webservice geladen wird, benötige ich eine andere Lösung.

    Mein Gedanke wäre nun, die Zeilen der Tabelle in Steps zurückzuliefern, aber ich hab momentan keine Idee, wie das gehen soll.
    Ich müsste ja den AJAX-Request in einer Schleife laufen lassen

    In einer Schleife so lange Tabellenzeilen holen, bis der Server das Ende meldet (etwa mit HTTP-Status 204 oder indem die Antwort immer aus einem JSON-Datensatz besteht, der aktuellen Status und HTML-Code kapselt), sollte das geringste Problem sein.

    bis PHP das Ende zurückmeldet

    So ich dich richtig verstanden habe, muss dein PHP-Skript selbst erst die Tabelle von woanders holen. Bevor du irgendwas anderes machst, wirst du dir überlegen müssen, wie du dieses Skript dazu bringst,
    a) asynchron Daten runterzuladen (asynchron vom Browser, denn der Browser soll ja nicht warten, bis es fertig ist),
    b) die bereits erhaltenen Daten ebenso asynchron an ein zweites Skript zu übergeben, welches die AJAX-Anfragen abarbeitet (asynchron von a),
    c) den ganzen doppelt asynchronen Ladeprozess für einen Benutzer nicht mehrfach zu starten, aber trotzdem mehrere Benutzer gleichzeitig zuzulassen.

    Grundsätzlich ist das alles möglich, die Frage wäre nur, ob der Aufwand sich lohnt, oder ob es eine andere Möglichkeit gibt. Vielleicht lässt sich die Tabelle ja vorbereiten und zwischenspeichern, so dass sie beim Laden durch den Browser schneller zur Verfügung steht.

    1. Per Klick auf einen Button rufe ich eine JS-Funktion auf und diese macht einen AJAX-Request an ein PHP-Script welches eine "Table" zurückliefert.
      Diese "Table" schreibe ich per JS in ein DIV.

      Da die Ladezeit aber sehr lange dauert, weil der Inhalt der "Table" über einen Webservice geladen wird, benötige ich eine andere Lösung.

      Mein Gedanke wäre nun, die Zeilen der Tabelle in Steps zurückzuliefern, aber ich hab momentan keine Idee, wie das gehen soll.
      Ich müsste ja den AJAX-Request in einer Schleife laufen lassen

      In einer Schleife so lange Tabellenzeilen holen, bis der Server das Ende meldet (etwa mit HTTP-Status 204 oder indem die Antwort immer aus einem JSON-Datensatz besteht, der aktuellen Status und HTML-Code kapselt), sollte das geringste Problem sein.

      bis PHP das Ende zurückmeldet

      So ich dich richtig verstanden habe, muss dein PHP-Skript selbst erst die Tabelle von woanders holen. Bevor du irgendwas anderes machst, wirst du dir überlegen müssen, wie du dieses Skript dazu bringst,
      a) asynchron Daten runterzuladen (asynchron vom Browser, denn der Browser soll ja nicht warten, bis es fertig ist),
      b) die bereits erhaltenen Daten ebenso asynchron an ein zweites Skript zu übergeben, welches die AJAX-Anfragen abarbeitet (asynchron von a),
      c) den ganzen doppelt asynchronen Ladeprozess für einen Benutzer nicht mehrfach zu starten, aber trotzdem mehrere Benutzer gleichzeitig zuzulassen.

      Grundsätzlich ist das alles möglich, die Frage wäre nur, ob der Aufwand sich lohnt, oder ob es eine andere Möglichkeit gibt. Vielleicht lässt sich die Tabelle ja vorbereiten und zwischenspeichern, so dass sie beim Laden durch den Browser schneller zur Verfügung steht.

      Die Tabelle besteht aus 10 Zeilen. Für jede Zeile muss ein Webservice-Aufruf gemacht werden und das inkl. Aufbereitung dauert ca. 1-3 Sekunden.
      einen Cache habe ich bereits eingerichtet und wenn die gleichen Daten ein zweites mal geladen werden sollen, geht das schneller - Aber in der Regel werden meist andere Daten angefragt.
      Somit liegt die Zeit bei ca. 20 Sekunden, was mir zu lange ist.

      Nun dachte ich, man könnte hinter einem Ladebalken die Tabelle Zeile für Zeile füllen, damit sich am Bildschirm etwas tut :-)

      Mir ist aber unklar, wie ich das machen kann.

      1. Mir ist aber unklar, wie ich das machen kann.

        Hm, warum nicht im Ajaxrequest einen Parameter tdnr einführen. Der ist initial 1. Im php script wertest Du den aus und holst Dir nur diese Zeile vom web service. Nun inkrementierst du tdnr entweder serverseitig oder im js des callbacks und verwendest ihn für den nächsten Ajaxrequest.

        Cheers,
        Baba

        --
        Baba kommt von Basketball
      2. Die Tabelle besteht aus 10 Zeilen. Für jede Zeile muss ein Webservice-Aufruf gemacht werden und das inkl. Aufbereitung dauert ca. 1-3 Sekunden.

        Nun dachte ich, man könnte hinter einem Ladebalken die Tabelle Zeile für Zeile füllen, damit sich am Bildschirm etwas tut :-)

        Da du für jede Zeile eine separate Rückfrage an den oder die Webservices im Hintergrund machst (ich war von einer für die ganze Tabelle ausgegangen), könnte sich die Angelegenheit deutlich vereinfachen.

        Auf Seite des Dokuments kannst du grundsätzlich genauso vorgehen wie bisher auch, nur, dass du die empfangenen Daten nicht in das <div> klemmst, sondern in ein stattdessen dafür vorgesehenes <tbody>- bzw. <table>-Element (das <div> schmeisst du raus, es sei denn, es hat noch eine andere Funktion).

        Verlagere die zehn Rückfragen aus dem PHP-Skript in den Javascript-Teil. Handelt es sich um nur einen Webservice, sollten alle Rückfragen nacheinander abgearbeitet werden. Sind es verschiedene, kannst du sie parallel starten.

        Die AJAX-Funktion bekommt als Parameter den abzufragenden Webservice (bzw. eine ID, die den Service beschreibt) und erwartet eine <tr>-Element als Antwort, die es an die Tabelle anhängt. Du bräuchtest im Javascript-Code nur die abzufragende URL ändern (Service-ID anklemmen) und HTML-seitig das id-Attribut vom alten <div> in die Tabelle verlegen.

        Im PHP-Skript fragst du je nach Service-ID den Webservice ab, formatierst, wie bisher auch, seine Antwort als <tr>-Element und gibst dieses aus.
        Hattest du im PHP-Skript bisher sowas:

        print("<table>")

        print("<tr>")
        daten = http.get("http://webservice1.example")
        print("<td>$platzhalter</td>", daten)
        print("<tr>")

        print("<tr>")
        daten = http.get("http://webservice2")
        print("<td>$platzhalter</td>", daten)
        print("<tr>")

        print("<tr>")
        daten = http.get("http://webservice3")
        print("<td>$platzhalter</td>", daten)
        print("<tr>")

        print("</table>")

        … machst du jetzt sowas:

        print("<tr>")
        if ($_GET["service"] == "1") then
           daten = http.get("http://webservice1")
           print("<td>$platzhalter</td>", daten)
        else if ($_GET["service"] == "2") then
           daten = http.get("http://webservice2")
           print("<td>$platzhalter</td>", daten)
        else if ($_GET["service"] == "3") then
           daten = http.get("http://webservice3")
           print("<td>$platzhalter</td>", daten)
        else
           print("<td>Kenn' ich nicht</td>")
        print("<tr>")

        Das ist jetzt nur ganz grob zur Veranschaulichung, es geht garantiert auch eleganter. Das hängt aber vom konkreten Anwendungsfall ab, bei nur einem Webservice mit gleichförmigen Antworten sollte da schon eine Liste mit den zehn Rückfrage-URLs zum Einsatz kommen, statt zehnmal die immer gleichen Anweisungen daten=hallo() & print(daten) hinzuschreiben. Ich habe es jetzt nur ausführlich hingeschrieben, da ich nicht weiss, was du wie abfragst.

        Falls du mit diesem Ansatz nicht weiterkommst, müsstest du deinen Code rausrücken, damit klar wird, wie die Rückfragen genau aussehen (URLs und Daten kannst du ja mit 1.example.com, 2.examle.com, etc. anonymisieren).

  2. Hallo zusammen,
    Soweit passt das.

    klar, warum nicht, die Tabelle serverseitig erzeugen und dann ins DOM zu hängen.

    Da die Ladezeit aber sehr lange dauert, weil der Inhalt der "Table" über einen Webservice geladen wird, benötige ich eine andere Lösung.

    Das Wissen um die Ursachen würde die Suche nach einer anderen Lösung etwas zielstrebiger gestalten. Wie groß ist denn die Tabelle, x, y? Wo ist die Datenquelle? Gibt es evntl. einen kürzeren Weg zur Datenbeschaffung, kann evntl. was gecached werden usw.

    MfG