Eu tenho uma série de chaves que levam a objetos de postagem para minha rede social, como / posts / id / (informações de postagem)
Quando eu carrego os posts eu carrego / posts / 0 e então / posts / 1 etc usando o observeSingleEventOfType(.Value)
método.
Eu uso um lazyTableView
para carregar 30 de cada vez e é bem lento. Existe alguma maneira de usar um dos métodos de consulta ou outra maneira de torná-lo mais rápido, mesmo se eu tiver que reestruturar os dados em minha árvore JSON.
Estou vindo do Parse reimplementando meu aplicativo e até agora a experiência tem sido muito boa. Só uma coisa em que estou um pouco preso. Obrigado antecipadamente pela ajuda!
EDITAR:
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
}
}
}
Essa função recursiva basicamente executa obtendo o valor da chave número i do firebase. Se for NSNULL, ele saberá que é a última postagem possível para carregar e nunca mais o fará. Se NSNULL não for atingido, i % 29 == 0
então ele retorna como um caso base, então apenas 30 posts são carregados por vez (0 indexado). Quando eu configuro doneLoading
para true
, tableView.reloadData()
é chamado usando um observador de propriedade.
Aqui está um exemplo de como é a matriz que estou buscando
"ideaPosts" : [ {
"id" : 0,
"message" : "Test",
"upvotes" : 1,
"user" : "Anonymous"
}, {
"id" : 1,
"message" : "Test2",
"upvotes" : 1,
"user" : "Anonymous"
} ]
Respostas:
Atualização: agora também cobrimos essa questão em um episódio do AskFirebase .
O carregamento de muitos itens do Firebase não precisa ser lento, pois você pode canalizar as solicitações. Mas o seu código está tornando isso impossível, o que certamente levará a um desempenho abaixo do ideal.
Em seu código, você solicita um item do servidor, espera que esse item retorne e carrega o próximo. Em um diagrama de sequência simplificado que se parece com:
Neste cenário, você está esperando 30 vezes o tempo de ida e volta + 30 vezes o tempo que leva para carregar os dados do disco. Se (por uma questão de simplicidade) dissermos que as viagens de ida e volta levam 1 segundo e o carregamento de um item do disco também leva um segundo, pelo menos até 30 * (1 + 1) = 60 segundos.
Em aplicativos Firebase, você obterá um desempenho muito melhor se enviar todas as solicitações (ou pelo menos um número razoável delas) de uma vez:
Se assumirmos novamente uma viagem de ida e volta de 1 segundo e 1 segundo de carregamento, você está esperando por 30 * 1 + 1 = 31 segundos.
Portanto: todas as solicitações passam pela mesma conexão. Dado isso, a única diferença entre
get(1)
,get(2)
,get(3)
egetAll([1,2,3])
é uma sobrecarga para os quadros.Eu configurei um jsbin para demonstrar o comportamento . O modelo de dados é muito simples, mas mostra a diferença.
Para comparação: o carregamento sequencial de 64 itens leva 3,8 segundos no meu sistema, enquanto carregá-los em pipeline (como o cliente Firebase faz nativamente) leva 600 ms. Os números exatos dependerão de sua conexão (latência e largura de banda), mas a versão em pipeline deve sempre ser significativamente mais rápida.
fonte