programing

단일 이벤트를 반복적으로 관찰하는 대신 쿼리를 사용하여 소셜 네트워크 앱에 대한 게시물 가져오기 속도 향상

jooyons 2023. 6. 24. 09:02
반응형

단일 이벤트를 반복적으로 관찰하는 대신 쿼리를 사용하여 소셜 네트워크 앱에 대한 게시물 가져오기 속도 향상

소셜 네트워크에 대한 개체를 게시할 수 있는 일련의 키가 있습니다. 예를 들어 /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

반응형