Mam tablicę kluczy, które prowadzą do publikowania obiektów w mojej sieci społecznościowej, takich jak: / posts / id / (informacje o wpisie)
Kiedy ładuję posty, ładuję / posts / 0, a następnie / posts / 1 itd., Używając observeSingleEventOfType(.Value)
metody.
Używam lazyTableView
do załadowania 30 na raz i jest to dość wolne. Czy istnieje sposób, w jaki mogę użyć jednej z metod zapytania lub innego sposobu na przyspieszenie, nawet jeśli muszę zmienić strukturę danych w moim drzewie JSON.
Pochodzę z Parse, ponownie wdrażam moją aplikację i jak dotąd doświadczenie jest całkiem dobre. Tylko ta jedna rzecz, na której trochę utknąłem. Z góry dziękuję za pomoc!
EDYTOWAĆ:
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
}
}
}
Ta rekurencyjna funkcja zasadniczo pobiera wartość klucza numer i z firebase. Jeśli jest to NSNULL, wie, że jest to ostatni możliwy do załadowania post i nigdy więcej tego nie robi. Jeśli NSNULL nie zostanie trafiony, ale i % 29 == 0
wróci jako przypadek podstawowy, więc tylko 30 postów jest ładowanych na raz (0 indeksowanych). Kiedy ustawiony doneLoading
do true
, tableView.reloadData()
nazywany jest przy użyciu właściwości obserwatora.
Oto próbka tego, jak wygląda tablica, którą pobieram
"ideaPosts" : [ {
"id" : 0,
"message" : "Test",
"upvotes" : 1,
"user" : "Anonymous"
}, {
"id" : 1,
"message" : "Test2",
"upvotes" : 1,
"user" : "Anonymous"
} ]
Odpowiedzi:
Aktualizacja: omawiamy teraz również to pytanie w odcinku AskFirebase .
Ładowanie wielu elementów z Firebase nie musi być powolne, ponieważ możesz potokować żądania. Ale twój kod uniemożliwia to, co rzeczywiście doprowadzi do nieoptymalnej wydajności.
W swoim kodzie żądasz elementu z serwera, czekasz, aż ten element wróci, a następnie załaduj następny. Na uproszczonym diagramie sekwencji, który wygląda następująco:
W tym scenariuszu czekasz 30-krotność czasu podróży w obie strony + 30-krotność czasu potrzebnego na załadowanie danych z dysku. Jeśli (dla uproszczenia) powiemy, że podróż w obie strony zajmuje 1 sekundę, a ładowanie elementu z dysku również zajmuje jedną sekundę, co najmniej do 30 * (1 + 1) = 60 sekund.
W aplikacjach Firebase uzyskasz znacznie lepszą wydajność, jeśli wyślesz wszystkie żądania (lub przynajmniej rozsądną ich liczbę) za jednym razem:
Jeśli ponownie przyjmiemy 1 sekundę podróży w obie strony i 1 sekundę ładowania, czekasz 30 * 1 + 1 = 31 sekund.
A więc: wszystkie żądania przechodzą przez to samo połączenie. Biorąc pod uwagę, że jedyna różnica między
get(1)
,get(2)
,get(3)
agetAll([1,2,3])
pewne napowietrznych do klatek.Założyłem jsbin wykazać zachowanie . Model danych jest bardzo prosty, ale pokazuje różnicę.
Dla porównania: sekwencyjne ładowanie 64 elementów zajmuje w moim systemie 3,8 sekundy, podczas gdy ładowanie ich potokiem (tak jak klient Firebase robi natywnie) zajmuje 600 ms. Dokładne liczby będą zależeć od twojego połączenia (opóźnienia i przepustowości), ale wersja potokowa zawsze powinna być znacznie szybsza.
źródło