Вы должны быть в состоянии оптимизировать время загрузки от 10-20 секунд до нескольких миллисекунд, начиная с denormalization.
Например, мы могли бы перемещать изображения и любые другие периферийные устройства, содержащие большую часть полезной нагрузки, в свой собственный путь, хранить только метаданные (имя, адрес электронной почты и т. Д.) В пользовательских записях и отдельно приобретать дополнительные функции:
/users/user_id/name, email, etc...
/images/user_id/...
количество слушателей событий прикреплении или пути подключения к не имеет каких-либо значительных накладных расходов на местном уровне или для сетей полосы пропускания (только полезная нагрузка), так что вы можете сделать что-то вроде этого «нормализовать» после захвата мета данные:
var firebaseRef = new Firebase(URL);
firebaseRef.child('users').on('child_added', function(snap) {
console.log('got user ', snap.name());
// I chose once() here to snag the image, assuming they don't change much
// but on() would work just as well
firebaseRef.child('images/'+snap.name()).once('value', function(imageSnap) {
console.log('got image for user ', imageSnap.name());
});
});
Вы сразу заметите, что, когда вы перемещаете основную часть данных и сохраняете только метаинформацию для пользователей локально, они будут молниеносно захватывать (все журналы журнала «got user» появятся сразу). Затем изображения будут просачиваться по одному за раз после этого, позволяя создавать полосы выполнения или обрабатывать их по мере их появления.
Если вы не хотите денормализовать данные, есть несколько способов разбить процесс загрузки. Вот простой pagination approach, чтобы захватить пользователей в сегментах:
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) {
// skip the startAt() entry, which we've already processed
if(userSnap.name() === lastEntry) { return; }
processUser(userSnap);
lastEntry = userSnap.name();
});
// setTimeout closes the call stack, allowing us to recurse
// infinitely without a maximum call stack error
setTimeout(grabNextTen.bind(null, ref, lastEntry);
});
}
function processUser(snap) {
console.log('got user', snap.name());
}
function didTenUsers(lastEntry) {
console.log('finished up to ', lastEntry);
}
Третий популярный подход будет хранить изображения в статическом облаке актива, как Amazon S3 и просто хранить URL-адреса в Firebase. Для больших наборов данных в сотнях тысяч это очень экономично, поскольку эти решения немного дешевле, чем хранилище Firebase.
Но я бы очень хотел, чтобы вы оба прочитали статью о денормализации и сначала инвестируете в этот подход.
Это правда, что child_added загружает исходный набор данных перед запуском событий. Есть несколько способов, которыми мы могли бы выполнить ваши цели здесь, но мне очень трудно понять пример использования, когда практически необходимо загрузить 10 МБ данных в браузер. Не могли бы вы рассказать о конечной цели, чтобы я мог лучше подобрать ответ на ваши нужды? – Kato
Конечно! Мне нужно загрузить список пользователей в определенном месте для приложения присутствия в реальном времени, которое я создаю. Каждый список большой, а некоторые списки содержат небольшие изображения с кодировкой base64, что увеличивает размер файла. Мне нужно показать пользователю список пользователей как можно быстрее, поэтому подход на основе потоков будет идеальным здесь. Ожидание 10-20 секунд для загрузки полного набора данных нецелесообразно по причинам удобства использования. – bcherny