3 Stimmen

Fortschrittsereignis für große Firebase-Abfragen?

Ich habe die folgende Abfrage:

fire = new Firebase 'ME.firebaseio.com'
users = fire.child 'venues/ID/users'
users.once 'value', (snapshot) ->
   # do things with snapshot.val()
   ...

Ich lade mehr als 10 MB an Daten und die Anfrage dauert ungefähr 1 Sekunde/MB. Ist es möglich, dem Benutzer einen Fortschrittsindikator zu geben, während der Inhalt einströmt? Idealerweise würde ich auch gerne die Daten verarbeiten, während sie eintreffen (nicht nur benachrichtigen).

Ich habe versucht, das on "child_added" Ereignis zu verwenden, aber es funktioniert nicht wie erwartet - anstatt dass die Kinder kontinuierlich eintreffen, kommen sie alle auf einmal, nachdem der gesamte Datensatz geladen ist (was 10-15 Sekunden dauert), also scheint es in der Praxis eine weniger performante Version von on "value" zu sein.

3voto

Kato Punkte 39518

Sie sollten in der Lage sein, Ihre Download-Zeit von 10-20 Sekunden auf einige Millisekunden zu optimieren, indem Sie mit einer gewissen Denormalisierung beginnen.

Zum Beispiel könnten wir die Bilder und andere Peripheriegeräte, die den Großteil der Nutzlast ausmachen, an einen eigenen Pfad verschieben, nur die Metadaten (Name, E-Mail usw.) in den Benutzerdatensätzen behalten und die Extras separat abrufen:

/users/user_id/name, email, etc...
/images/user_id/...

Die Anzahl der Ereignislistener, die Sie anhängen oder Pfade, die Sie verbinden, haben lokal oder für die Netzwerkbandbreite keine signifikante Überlastung (nur die Nutzlast), sodass Sie nach dem Abrufen der Metadaten etwas Ähnliches wie dies tun können, um nach dem Abrufen der Metadaten zu "normalisieren":

var firebaseRef = new Firebase(URL);
firebaseRef.child('users').on('child_added', function(snap) {
   console.log('Benutzer erhalten ', snap.name());

   // Ich habe hier once() ausgewählt, um das Bild zu ergattern, unter der Annahme, dass sie sich nicht oft ändern
   // aber on() würde genauso gut funktionieren
   firebaseRef.child('images/'+snap.name()).once('value', function(imageSnap) {
       console.log('Bild für Benutzer erhalten ', imageSnap.name());
   });
});

Sie werden sofort feststellen, dass, wenn Sie den Großteil der Daten herausnehmen und nur die Metainformationen für Benutzer lokal behalten, sie blitzschnell abgerufen werden (alle "Benutzer erhalten"-Protokolle erscheinen sofort). Dann werden die Bilder nacheinander eintreffen, was es Ihnen ermöglicht, Fortschrittsbalken zu erstellen oder sie zu verarbeiten, sobald sie auftauchen.

Wenn Sie nicht bereit sind, die Daten zu denormalisieren, gibt es ein paar Möglichkeiten, wie Sie den Ladeprozess aufteilen könnten. Hier ist ein einfacher Seitenapproach, um die Benutzer in Segmenten abzurufen:

var firebaseRef = new Firebase(URL);
grabNextTen(firebaseRef, null);

function grabNextTen(ref, startAt) {
   ref.limit(startAt? 11 : 10).startAt(startAt).once('value', function(snap) {
      var lastEntry;
      snap.forEach(function(userSnap) {
         // überspringen des StartAt()-Eintrags, den wir bereits verarbeitet haben
         if( userSnap.name() === lastEntry ) { return; }
         processUser(userSnap);
         lastEntry = userSnap.name();
      });

      // setTimeout schließt den Funktionsaufruf-Stack, sodass wir rekursiv weitermachen können
      // endlos ohne einen Fehler für den maximalen Funktionsaufrufstack
      setTimeout(grabNextTen.bind(null, ref, lastEntry);
   });
}

function processUser(snap) {
   console.log('Benutzer erhalten', snap.name());
}

function didTenUsers(lastEntry) {
   console.log('bis ', lastEntry, 'fertig');
}

Ein dritter beliebter Ansatz wäre, die Bilder in einem statischen Cloud-Asset wie Amazon S3 zu speichern und einfach die URLs in Firebase zu speichern. Für große Datensätze im Hunderttausendenbereich ist dies sehr wirtschaftlich, da diese Lösungen etwas günstiger sind als Firebase-Speicherlösungen.

Aber ich würde Ihnen dringend raten, sowohl den Artikel zur Denormalisierung zu lesen als auch in diesen Ansatz zu investieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X