chore(Feed): Improve Feed performance by fetching statuses in batches (#914)

This commit is contained in:
Marcus Kida 2023-02-07 00:46:35 +01:00 committed by GitHub
parent 0a9689c67f
commit 3b87916d9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 3 deletions

View File

@ -518,6 +518,12 @@ extension HomeTimelineViewController: UITableViewDelegate, AutoGenerateTableView
}
// sourcery:end
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 {
viewModel.timelineDidReachEnd()
}
}
}
// MARK: - TimelineMiddleLoaderTableViewCellDelegate

View File

@ -65,7 +65,7 @@ extension HomeTimelineViewModel.LoadLatestState {
guard let viewModel else { return }
let latestFeedRecords = viewModel.fetchedResultsController.records.prefix(APIService.onceRequestStatusMaxCount)
let parentManagedObjectContext = viewModel.fetchedResultsController.fetchedResultsController.managedObjectContext
let parentManagedObjectContext = viewModel.fetchedResultsController.managedObjectContext
let managedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
managedObjectContext.parent = parentManagedObjectContext

View File

@ -67,7 +67,7 @@ extension HomeTimelineViewModel.LoadOldestState {
}
Task {
let managedObjectContext = viewModel.fetchedResultsController.fetchedResultsController.managedObjectContext
let managedObjectContext = viewModel.fetchedResultsController.managedObjectContext
let _maxID: Mastodon.Entity.Status.ID? = try await managedObjectContext.perform {
guard let feed = lastFeedRecord.object(in: managedObjectContext),
let status = feed.status

View File

@ -119,6 +119,12 @@ extension HomeTimelineViewModel {
}
}
extension HomeTimelineViewModel {
func timelineDidReachEnd() {
fetchedResultsController.fetchNextBatch()
}
}
extension HomeTimelineViewModel {
// load timeline gap

View File

@ -16,11 +16,19 @@ import MastodonSDK
final public class FeedFetchedResultsController: NSObject {
private enum Constants {
static let defaultFetchLimit = 100
}
public let logger = Logger(subsystem: "FeedFetchedResultsController", category: "DB")
var disposeBag = Set<AnyCancellable>()
public let fetchedResultsController: NSFetchedResultsController<Feed>
private let fetchedResultsController: NSFetchedResultsController<Feed>
public var managedObjectContext: NSManagedObjectContext {
fetchedResultsController.managedObjectContext
}
// input
@Published public var predicate = Feed.predicate(kind: .none, acct: .none)
@ -28,6 +36,11 @@ final public class FeedFetchedResultsController: NSObject {
// output
private let _objectIDs = PassthroughSubject<[NSManagedObjectID], Never>()
@Published public var records: [ManagedObjectRecord<Feed>] = []
public func fetchNextBatch() {
fetchedResultsController.fetchRequest.fetchLimit += Constants.defaultFetchLimit
try? fetchedResultsController.performFetch()
}
public init(managedObjectContext: NSManagedObjectContext) {
self.fetchedResultsController = {
@ -36,6 +49,7 @@ final public class FeedFetchedResultsController: NSObject {
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.shouldRefreshRefetchedObjects = true
fetchRequest.fetchBatchSize = 15
fetchRequest.fetchLimit = Constants.defaultFetchLimit
let controller = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: managedObjectContext,