FirebaseUI-iOS icon indicating copy to clipboard operation
FirebaseUI-iOS copied to clipboard

Firebase UI Database very slow to load content

Open joemerritt opened this issue 6 years ago • 8 comments

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
    }

joemerritt avatar Oct 29 '18 11:10 joemerritt

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

morganchen12 avatar Oct 31 '18 17:10 morganchen12

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

josephkabba avatar Mar 31 '20 21:03 josephkabba

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

joemerritt avatar Jan 30 '21 00:01 joemerritt

Are you experiencing this without using FirebaseUI?

morganchen12 avatar Feb 01 '21 23:02 morganchen12

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
    })

joemerritt avatar Feb 17 '21 05:02 joemerritt

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.

morganchen12 avatar Feb 17 '21 18:02 morganchen12

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

joemerritt avatar Feb 20 '21 03:02 joemerritt

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.

morganchen12 avatar Feb 23 '21 22:02 morganchen12