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.