У меня есть массив ключей, которые ведут к объектам публикации для моей социальной сети, например / posts / id / (информация о публикации)
Когда я загружаю сообщения, я загружаю / posts / 0, а затем / posts / 1 и т.д., используя этот observeSingleEventOfType(.Value)
метод.
Я использую lazyTableView
для загрузки 30 за раз, и это довольно медленно. Могу ли я использовать один из методов запроса или другой способ сделать его быстрее, даже если мне придется реструктурировать данные в моем дереве JSON.
Я исхожу из Parse, повторно реализую свое приложение, и до сих пор опыт был довольно хорошим. Только вот в чем я немного зациклился. Заранее спасибо за помощь!
РЕДАКТИРОВАТЬ:
func loadNext(i: Int) {
// check if exhists
let ideaPostsRef = Firebase(url: "https://APPURL")
ideaPostsRef.childByAppendingPath(i.description).observeSingleEventOfType(.Value, withBlock: {
(snapshot) in
if i % 29 == 0 && i != 0 && !self.hitNull { return }
// false if nil
// true if not nil
if !(snapshot.value is NSNull) {
let postJSON = snapshot.value as! [String: AnyObject]
print("GOT VALID \(postJSON)")
let post = IdeaPost(message: postJSON["message"] as! String, byUser: postJSON["user"] as! String, withId: i.description)
post.upvotes = postJSON["upvotes"] as! Int
self.ideaPostDataSource.append(post)
self.loadNext(i + 1)
} else {
// doesn't exhist
print("GOT NULL RETURNING AT \(i)")
self.doneLoading = true
self.hitNull = true
return
}
}
}
Эта рекурсивная функция, по сути, выполняет получение значения ключа i из firebase. Если это NSNULL, он знает, что это последний пост, который можно загрузить, и больше никогда не загружается. Если NSNULL не попадает, но i % 29 == 0
затем возвращается как базовый случай, поэтому одновременно загружается только 30 сообщений (0 проиндексировано). Когда я установил doneLoading
значение true
, tableView.reloadData()
вызывается с помощью обозревателя свойств.
Вот пример того, как выглядит массив, который я получаю
"ideaPosts" : [ {
"id" : 0,
"message" : "Test",
"upvotes" : 1,
"user" : "Anonymous"
}, {
"id" : 1,
"message" : "Test2",
"upvotes" : 1,
"user" : "Anonymous"
} ]
Ответы:
Обновление: теперь мы также рассмотрим этот вопрос в эпизоде AskFirebase .
Загрузка большого количества элементов из Firebase не должна быть медленной, поскольку вы можете конвейерно обрабатывать запросы. Но ваш код делает это невозможным, что действительно приведет к неоптимальной производительности.
В вашем коде вы запрашиваете элемент с сервера, ждете, пока этот элемент вернется, а затем загружаете следующий. На упрощенной диаграмме последовательности, которая выглядит так:
В этом сценарии вы ждете в 30 раз больше времени, чем требуется для загрузки данных с диска. Если (для простоты) мы скажем, что обратное обращение занимает 1 секунду, а загрузка элемента с диска также занимает одну секунду, что меньше 30 * (1 + 1) = 60 секунд.
В приложениях Firebase вы получите намного лучшую производительность, если отправите все запросы (или, по крайней мере, их разумное количество) за один раз:
Если мы снова примем 1 секунду туда и обратно и 1 секунду загрузки, вы ждете 30 * 1 + 1 = 31 секунду.
Итак: все запросы проходят через одно и то же соединение. Учитывая , что единственное различие между
get(1)
,get(2)
,get(3)
иgetAll([1,2,3])
некоторые накладные расходы для кадров.Я установил jsbin, чтобы продемонстрировать поведение . Модель данных очень проста, но она демонстрирует разницу.
Для сравнения: последовательная загрузка 64 элементов в моей системе занимает 3,8 секунды, а конвейерная загрузка (как это делает клиент Firebase изначально) - 600 мс. Точные числа будут зависеть от вашего соединения (задержки и пропускной способности), но конвейерная версия всегда должна быть значительно быстрее.
источник