বারবার কোনও একক ইভেন্ট পর্যবেক্ষণ না করে কোয়েরি ব্যবহার করে আমার সামাজিক নেটওয়ার্ক অ্যাপ্লিকেশনটির জন্য পোস্টগুলি দ্রুততর করুন


98

আমার কাছে এমন কীগুলির একটি অ্যারে রয়েছে যা আমার সামাজিক নেটওয়ার্কের জন্য যেমন / পোস্টস / আইডি / (পোস্ট তথ্য) এর মতো অবজেক্ট পোস্ট করতে পারে

আমি যখন পোস্টটি লোড করি / পোস্টগুলি / 0 এবং তারপরে / পোস্টগুলি / 1 ইত্যাদি observeSingleEventOfType(.Value)পদ্ধতিটি ব্যবহার করে ।

আমি lazyTableViewএকবারে 30 লোড করতে একটি ব্যবহার করি এবং এটি বেশ ধীর হয়। আমার জেএসওন ট্রিতে ডেটা পুনর্গঠন করতে হবে এমন কি আমি কোয়েরির পদ্ধতিগুলির একটি বা এটি দ্রুততর করার অন্য কোনও উপায় ব্যবহার করতে পারি?

আমি পার্সে আমার অ্যাপ্লিকেশনটি পুনরায় বাস্তবায়ন করতে এসেছি এবং এখনও পর্যন্ত অভিজ্ঞতাটি বেশ ভাল ছিল। শুধু এই একটি জিনিস আমি কিছুটা আটকে আছি। সাহায্যের জন্য আগাম ধন্যবাদ!

সম্পাদনা:

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 এর মান পেয়ে চলে। যদি এটি এনএসএনআলুল হয় তবে এটি জানেন যে এটি লোড করার শেষ সম্ভাব্য পোস্ট এবং আর কখনও না। যদি এনএসএনএলএল হিট না হয়ে থাকে 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"
  } ]

4
আপনি যদি আপনার কোডটি বর্ণনা না দিয়ে আমাদের কোড দেখান তবে সাহায্য করা অনেক সহজ হবে। আপনার প্রশ্নের সমস্যাটিকে পুনরুত্পাদন করার জন্য সর্বনিম্ন জেএসএন (পাঠ্য হিসাবে, স্ক্রিনশট নয়) এবং কোড অন্তর্ভুক্ত করুন এবং আমরা দেখতে পারি যে এটি কীভাবে উন্নত করা যায়। একটি MCVE সম্পর্কে আরও পড়ুন ।
ফ্রাঙ্ক ভ্যান পাফেলেন

কোড ব্যাখ্যা অন্তর্ভুক্ত করতে সম্পাদিত
4_8 এ বড়_ম্যাক

উত্তর:


125

আপডেট: আমরা এখন এই প্রশ্নটি একটি এসকফায়ারবেস পর্বেও কভার করি ।

ফায়ারবেস থেকে অনেকগুলি আইটেম লোড করা ধীর হতে হবে না, যেহেতু আপনি অনুরোধগুলি পাইপলাইন করতে পারেন। তবে আপনার কোডটি এটি অসম্ভব করে দিচ্ছে, যা প্রকৃতপক্ষে উপ-পারফরম্যান্সের দিকে পরিচালিত করবে।

আপনার কোডে আপনি সার্ভার থেকে একটি আইটেমের জন্য অনুরোধ করেছেন, সেই আইটেমটি ফিরে আসার জন্য অপেক্ষা করুন এবং তারপরে পরবর্তীটি লোড করুন। সরলীকৃত অনুক্রমের ডায়াগ্রামের মতো দেখতে:

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 সেকেন্ড নেয় এবং ডিস্ক থেকে কোনও আইটেম লোড করতেও এক সেকেন্ড লাগে যা কমপক্ষে 30 * (1 + 1) = 60 সেকেন্ডে লাগে।

আপনি যদি একবারে সমস্ত অনুরোধগুলি (বা কমপক্ষে যুক্তিসঙ্গত সংখ্যার) প্রেরণ করেন তবে ফায়ারবেস অ্যাপ্লিকেশনগুলিতে আপনি আরও ভাল পারফরম্যান্স পাবেন:

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])ফ্রেমের জন্য কিছু উপরি হয়।

আমি আচরণটি প্রদর্শনের জন্য একটি জেসবিন স্থাপন করেছি । ডেটা মডেলটি খুব সহজ, তবে এটি পার্থক্যটি দেখায়।

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৪ টি আইটেম লোড করতে আমার সিস্টেমে ৩.৮ সেকেন্ড সময় লাগে, যখন সেগুলি পাইপলাইনে লোড করার সময় (ফায়ারবেস ক্লায়েন্ট স্থানীয়ভাবে করে) এটি 600 মিমি লাগে। সঠিক সংখ্যাগুলি আপনার সংযোগের উপর নির্ভর করবে (বিলম্ব এবং ব্যান্ডউইথ), তবে পাইপলাইনযুক্ত সংস্করণটি সর্বদা উল্লেখযোগ্যভাবে দ্রুত হওয়া উচিত।


12
ভাল লাগল, পুফ! এছাড়াও, শৃঙ্খলাবদ্ধ প্রতিশ্রুতি (jQuery.whenAll (), q.all (), বা প্রতিশ্রুতি.সকল ()) এখানে আপনার যদি সমস্ত জিনিস বোঝা প্রয়োজন হয় তবে খুব কার্যকর হতে পারে তবে কিছু পদক্ষেপ নেওয়ার আগে এগুলি সমান্তরালে ধরতে চান।
কাতো

5
শীতল। এমনকি আমি এটি ব্যবহার করেও এটি ভেবে দেখিনি। :-)
ফ্র্যাঙ্ক ভ্যান পাফেলেন

4
@ ফ্র্যাঙ্কওয়ানপুফেলেন আপনি পারফরম্যান্সের দৃষ্টিকোণ থেকে ঠিক আছেন তবে এই ধরণের কোনও কল যদি কোনও ধরণের ত্রুটির কারণে না ফিরে আসে? যদি এর মধ্যে কেউ ব্যর্থ হয় তবে আপনি কীভাবে মুলতুবি থাকা অনুরোধগুলি 'বাতিল' করতে পারেন। ক্রমযুক্ত অনুরোধগুলির ক্ষেত্রে, আমরা কোডটিতে জানতে পারি যে কোন অনুরোধটি ব্যর্থ হয়েছিল। আপনার চিন্তা ভাগ করুন। ধন্যবাদ
পেরি

4
"প্রতিশ্রুতি । সমস্ত () পদ্ধতি [...] প্রত্যাখাত প্রথম প্রতিশ্রুতির কারণ দিয়ে প্রত্যাখ্যান করে।"
পেজালো

4
অ্যান্ড্রয়েডে আমরা কীভাবে প্রতিশ্রুতি দিতে পারি? অ্যান্ড্রয়েডে আমরা কীভাবে সমস্ত ডেটা লোড করতে পারি
মুহাম্মদ ছোটা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.