Что такое пагинация в контексте разработки приложений?

Ответ

Пагинация — это метод разбиения большого набора данных на отдельные страницы (части) для их последовательной загрузки и отображения.

Зачем это нужно?

  • Оптимизация производительности: Загрузка всех данных сразу потребляет много памяти и времени.
  • Улучшение UX: Пользователь видит первую часть контента мгновенно, а остальное подгружается по мере необходимости (например, при скролле).
  • Снижение нагрузки на сервер и сеть: Передаются только запрошенные порции данных.

Типичная реализация на iOS (UICollectionView/UITableView):

class ViewController: UIViewController {
    var data: [Item] = []
    var currentPage = 1
    var isLoading = false
    var isLastPage = false

    func loadNextPage() {
        guard !isLoading && !isLastPage else { return }
        isLoading = true
        // Показать индикатор загрузки

        NetworkService.fetchPage(currentPage) { [weak self] result in
            guard let self = self else { return }
            self.isLoading = false
            // Скрыть индикатор загрузки

            switch result {
            case .success(let newItems):
                if newItems.isEmpty {
                    self.isLastPage = true
                } else {
                    self.data.append(contentsOf: newItems)
                    self.currentPage += 1
                    self.tableView.reloadData()
                }
            case .failure(let error):
                // Обработать ошибку
                print(error)
            }
        }
    }
}

// Триггер подгрузки при достижении конца списка
extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if indexPath.row == data.count - 1 {
            loadNextPage()
        }
    }
}

Ключевые состояния для обработки: loading, error, last page reached. На сервере пагинация часто реализуется через параметры запроса ?page=1&limit=20 или курсоры (cursor).

Ответ 18+ 🔞

А, пагинация, блядь! Ну это когда у тебя данных — овердохуища, как в моей голове после пятницы, и показывать всё сразу — это пиздец как долго и бессмысленно.

Зачем это вообще, нахуй?

  • Чтобы не ебланить систему: Если грузить всё и сразу, приложение сожрёт всю память и сдохнет, как муха в супе. Сервер тоже охуеет от такого запроса.
  • Чтоб пользователь не охуел от ожидания: Он сразу видит первую страницу, а дальше контент подгружается потихоньку, пока он скроллит. Удобно, ёпта!
  • Разгрузить всё нахуй: И серверу легче, и сеть не забивается огромной кучей данных за раз.

Вот как это обычно выглядит в коде для iOS, если делать по-человечески:

class ViewController: UIViewController {
    var data: [Item] = [] // Тут наши данные копятся
    var currentPage = 1 // Начинаем, естественно, с первой страницы
    var isLoading = false // Чтобы не дрочить сервер десятью запросами одновременно
    var isLastPage = false // Флаг, что всё, пиздец, кончились данные

    func loadNextPage() {
        // Если уже грузим или уже всё загрузили — иди нахуй, не мешай
        guard !isLoading && !isLastPage else { return }
        isLoading = true
        // Тут можно крутилку какую-нибудь показать, типа "жди, сука"

        NetworkService.fetchPage(currentPage) { [weak self] result in
            guard let self = self else { return }
            self.isLoading = false // Всё, отдышались
            // Убираем крутилку

            switch result {
            case .success(let newItems):
                if newItems.isEmpty {
                    // Если пришёл пустой массив — всё, кончилось, дальше некуда
                    self.isLastPage = true
                } else {
                    // Ага, есть что добавить! Кидаем новые данные в общую кучу
                    self.data.append(contentsOf: newItems)
                    self.currentPage += 1 // Готовимся к следующей странице
                    self.tableView.reloadData() // Обновляем таблицу
                }
            case .failure(let error):
                // Ну вот, обосрались. Обрабатываем ошибку как умеем.
                print("Ёпта, ошибка: (error)")
            }
        }
    }
}

// А это магия, которая запускает подгрузку, когда пользователь дополз до конца списка
extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        // Если показали последнюю ячейку из того, что есть — пора грузить ещё!
        if indexPath.row == data.count - 1 {
            loadNextPage()
        }
    }
}

Главное тут — не накосячить с состояниями: вот сейчас грузим (loading), вот всё заебись, вот ошибочка вышла, а вот уже всё, хуйня, страниц больше нет (last page reached). На сервере обычно тоже делают просто: либо ?page=2&limit=20, либо через какую-нибудь умную штуку — курсор. В общем, идея ясна, как божий день.