단일 이벤트를 반복적으로 관찰하는 대신 쿼리를 사용하여 소셜 네트워크 앱에 대한 게시물 가져오기 속도 향상
소셜 네트워크에 대한 개체를 게시할 수 있는 일련의 키가 있습니다. 예를 들어 /posts/id/(postinfo)
게시물을 로드할 때 /posts/0을 로드한 다음 /posts/1 등을 사용하여 로드합니다.observeSingleEventOfType(.Value)방법.
사용합니다.lazyTableView한 번에 30개를 적재하는 것은 꽤 느립니다.JSON 트리의 데이터를 재구성해야 하는 경우에도 쿼리 방법 중 하나를 사용하거나 더 빠르게 만들 수 있는 다른 방법이 있습니까?
저는 제 앱을 재구현하는 파스에서 왔고 지금까지 경험은 꽤 좋았습니다.딱 한 가지 제가 집착하고 있는 것이 있습니다.
편집:
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의 값을 가져오는 것으로 실행됩니다.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에서 많은 항목을 로드하는 속도가 느릴 필요가 없습니다.하지만 당신의 코드는 이것을 불가능하게 만들고 있으며, 이것은 실제로 차선의 성능으로 이어질 것입니다.
코드에서 서버에 항목을 요청하고 해당 항목이 반환될 때까지 기다린 후 다음 항목을 로드합니다.다음과 같은 단순화된 시퀀스 다이어그램:
Your app Firebase
Database
-- request item 1 -->
S L
e o
r a
v d
e i
<- return item 1 -- r n
g
-- request item 2 -->
S L
e o
r a
v d
e i
r n
<- return item 2 -- g
-- request item 3 -->
.
.
.
-- request item 30-->
S L
e o
r a
v d
e i
r n
g
<- return item 30 --
이 시나리오에서는 왕복 시간의 30배 + 디스크에서 데이터를 로드하는 데 걸리는 시간의 30배를 기다립니다.(간단함을 위해) 왕복에 1초가 걸리며 디스크에서 항목을 로드하는 데도 최소 1초가 걸린다고 하면 30 * (1 + 1) = 60초가 걸립니다.
Firebase 응용프로그램에서 모든 요청(또는 적어도 상당한 수의 요청)을 한 번에 전송하면 성능이 훨씬 향상됩니다.
Your app Firebase
Database
-- request item 1 -->
-- request item 2 --> S L
-- request item 3 --> e o
. r a
. v d
. e i
-- request item 30--> r n
g
<- return item 1 --
<- return item 2 --
<- return item 3 --
.
.
.
<- return item 30 --
다시 1초의 왕복과 1초의 로딩을 가정하면 30*1 + 1 = 31초 동안 기다립니다.
따라서 모든 요청은 동일한 연결을 통해 이루어집니다.그 점을 고려할 때, 사이의 유일한 차이점은get(1),get(2),get(3)그리고.getAll([1,2,3])프레임에 대한 오버헤드입니다.
저는 그 행동을 보여주기 위해 jsbin을 설치했습니다.데이터 모델은 매우 단순하지만 차이점을 보여줍니다.
function loadVideosSequential(videoIds) {
if (videoIds.length > 0) {
db.child('videos').child(videoIds[0]).once('value', snapshot => {
if (videoIds.length > 1) {
loadVideosSequential(videoIds.splice(1), callback)
}
});
}
}
function loadVideosParallel(videoIds) {
Promise.all(
videoIds.map(id => db.child('videos').child(id).once('value'))
);
}
비교를 위해: 64개 항목을 순차적으로 로드하는 데는 시스템에서 3.8초가 소요되는 반면, 파이프라인으로 로드하는 데는 600ms가 소요됩니다. 클라이언트가 기본적으로 로드하는 것처럼) 600ms가 소요됩니다.정확한 숫자는 연결(지연 및 대역폭)에 따라 다르지만 파이프라인 버전은 항상 상당히 빨라야 합니다.
언급URL : https://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse
'programing' 카테고리의 다른 글
| 캔 포스트그레SQL 인덱스 배열 열? (0) | 2023.06.24 |
|---|---|
| Spring Boot 애플리케이션을 종료하는 동안 DataSource JMX Mean의 등록을 취소하지 못함 (0) | 2023.06.24 |
| excel.js 모듈 + 노드를 사용하여 열 머리글 앞에 행 추가 (0) | 2023.06.24 |
| 서로 다른 인증 공급자와 함께 여러 WebSecurityConfigurerAdapter 사용(API용 기본 인증자 및 웹 앱용 LDAP) (0) | 2023.06.24 |
| MariaDB 10.3.9 시스템 버전 테이블에서 DateTime 사용은 rowStart에는 작동하지만 rowEnd에는 작동하지 않습니다. (0) | 2023.06.24 |