xmartlabs / Eureka

Elegant iOS form builder in Swift
https://eurekacommunity.github.io
MIT License
11.78k stars 1.33k forks source link

How can we optimize .evaluateHidden() performance? #1932

Open sedwo opened 5 years ago

sedwo commented 5 years ago

Using Eureka v5.1.0

I've implemented a UISearchController in my VC which works with Eureka like this:

func updateSearchResults(for searchController: UISearchController) {

    guard let searchText = searchController.searchBar.text else { return }

    // Get the unwrapped (nested optionals) values of all rows which have a 'Tag' assigned.
    // The dictionary contains the [rowTag:value] pairs.
    let valuesDictionary = form.unwrappedValues(includeHidden: true)    // small extension

    let startTime = CFAbsoluteTimeGetCurrent()
    var showSpinner = false

    // Filter rows based on search criteria.
    for keyValue in valuesDictionary {
        if let value = keyValue.value as? String, let row = form.rowBy(tag: keyValue.key) {
            var hide: Bool = false

            if searchText != "" {
                hide = value.lowercased().contains(searchText.lowercased()) ? false : true
            }

            row.hidden = Condition(booleanLiteral: hide)

            UIView.performWithoutAnimation {
                row.evaluateHidden()
            }
        }

        // Evaluate our running time for this process loop, and display spinner if we're past a threshold of seconds.
        let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
        if timeElapsed > 0.25 && showSpinner == false {
            showSpinner = true
            DDLogInfo("⏱ processing time elapsed: \(timeElapsed)")
            self.showActivityIndicator(withStatus: "processing", containerView: self.tableView)
        }

    }

    self.dismissAllIndicatorActivity()

}

For small lists, ~50 rows, the performance does well enough. But once I hit several hundred rows, the user experience breaks down and forces me to put up a spinner while Eureka processes its row.evaluateHidden() UI. 😢

What optimization can be done to alleviate this bottleneck such that Eureka improves its performance with larger forms of rows?

mats-claassen commented 4 years ago

Eureka was thought primarily for smaller forms (think of a Settings form) and not long lists of rows. For example, Eureka does not reuse cells which can also be a problem with many rows. We recommend using a simple UITableView for such cases.

What we would have to implement in Eureka to improve this is either a function to "evaluateHidden" an array of rows and possibly call that function on all rows that depend on the same value. For example, in your case you could make all rows depend on the value of the searchBar if that is also a row in the Form