firebase / FirebaseUI-iOS

iOS UI bindings for Firebase.
Apache License 2.0
1.51k stars 475 forks source link

Firebase UI Database very slow to load content #553

Open joemerritt opened 5 years ago

joemerritt commented 5 years ago

Hi All,

I'm currently using FIrebaseUI to load data by simply connecting a query to a tableview. When loading the initial the tableview the datasource goes through all nodes in "Adverts".

As i have a lot of nodes this take a prolonged amount of time. IE. "Datasource Started" is call the number of times that I have nodes. Once finished the data works the way i want and it's call as needed ..... Is there a way to shorten this initial load time?

let dataRef = ref.child("Adverts")

self.dataSource = self.listTableView.bind(to: dataRef) { tableView, indexPath, snapshot in

        self.cell = self.listTableView.dequeueReusableCell(withIdentifier: "customMessageCell", for: indexPath) as? CustomMessageCell

        print("Datasource Started")

       //populate cell here

        return self.cell
    }
morganchen12 commented 5 years ago

Can you run an instruments trace to see what's taking up the most time?

josephkabba commented 4 years ago

yes this is true. it takes time to initially load. it takes like 10 seconds

joemerritt commented 3 years ago

Hi Gents, was there a solution to this? I currently have a node with approx 50 children. It takes approx 1-2 seconds to return and start loading.

From the output it appears to cycle through all 50 children before it loads. I

I've put my indexon rules in place. however this does not improve performance.

I'm afraid that when my data base has excessive children this will be a significant issue?

Any help would be appreciated

morganchen12 commented 3 years ago

Are you experiencing this without using FirebaseUI?

joemerritt commented 3 years ago

Hi Morganchen,

Apologies for the late response. I"ve been using the below bind for a Tableview, the problem comes when running the code the print line "Trigger 1" gets fired for every node that's the in reference. Ie if there are 200 nodes, Trigger 1 prints 200 times per cell. Obviously this takes a lot of time.

Once Triggers 200 times. It works like it should by only calling the cells coming into view.

Any idea why this maybe happening?

 let refQuery = refCol.child("Adverts").child(importUid).queryOrdered(byChild: "negAdded")
 self.dataSource = self.ownerTableView.bind(to: refQuery, populateCell: { (tableView, indexPath, snapshot) -> UITableViewCell in

        print(" Trigger 1: \(indexPath)")

        let cell = self.ownerTableView.dequeueReusableCell(withIdentifier: "mainCell", for: indexPath) as! MainTableViewCell

        *do stuff here

        return cell
    })
morganchen12 commented 3 years ago

This happens because FirebaseUI's built-in table view data source processes each update individually, causing the table view to consume a lot of time. You can work around this for the time being by subclassing the FUITableViewDataSource class and overriding the methods that handle database event updates.

The most straightforward way to improve performance here is to just batch the updates or disable animations on the updates.

joemerritt commented 3 years ago

Hi Morganchen,

Sorry to be a pain on this. I understand what you are saying, but am having trouble on execution. Is there an example of where this has been done? I'm not a pro, so any help you can give me on this would be great

Also does this apply for collection view? I"m having the same problem

Cheers

Joe

morganchen12 commented 3 years ago

In the simplest case, you should be able to (for example) subclass FUITableViewDataSource and implement the following functions:

#pragma mark - FUICollectionDelegate methods

- (void)array:(FUIArray *)array didAddObject:(id)object atIndex:(NSUInteger)index {
  [self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:index inSection:0] ]
                        withRowAnimation: UITableViewRowAnimationNone];
}

- (void)array:(FUIArray *)array didChangeObject:(id)object atIndex:(NSUInteger)index {
  [self.tableView reloadRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:index inSection:0] ]
                        withRowAnimation: UITableViewRowAnimationNone];
}

- (void)array:(FUIArray *)array didRemoveObject:(id)object atIndex:(NSUInteger)index {
  [self.tableView deleteRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:index inSection:0] ]
                        withRowAnimation: UITableViewRowAnimationNone];
}

This will disable animations on row updates.