Paginatsiya — mobil ilovalar va veb xizmatlarda katta ma'lumotlar to'plamlari bilan ishlash uchun ishlatiladigan sahifama-sahifa ma'lumot yuklash texnikasi. Android Developers Documentation (2025) ga ko'ra, paginatsiyaning to'g'ri qo'llanilishi API yukini kamaytiradi, trafikni tejaydi va foydalanuvchi tajribasini yaxshilaydi. Sahifama-sahifa yuklash ilovaga kontentni asta-sekin, barcha ma'lumotlarning to'liq yuklanishini kutmasdan ko'rsatishga imkon beradi.
Asosiy fikrlar
Paginatsiya (ing. pagination — sahifalarga bo'lish) — katta ma'lumotlar to'plamini ketma-ket qismlarga (sahifalarga) ajratish texnikasi. Mobil ilovalarda paginatsiya xabarlar ro'yxati, yangiliklar lentasi, mahsulot kataloglari, buyurtmalar tarixi va potensial cheksiz sonli yozuvlarga ega boshqa kolleksiyalarni yuklashda ishlatiladi.
Paginatsiyasiz ilova barcha ma'lumotlarni birdan yuklashga majbur, bu esa uzoq kutishga, katta trafik sarfiga va zaif qurilmalarda beqaror ishlashga olib keladi. Paginatsiyali API so'rovi faqat bitta qism ma'lumot va keyingisini yuklash uchun meta-ma'lumot qaytaradi — shu tarzda ilova olinadigan ma'lumot hajmini nazorat qiladi.
Paginatsiyaning asosiy ko'rsatkichlari: sahifa hajmi (page size) — bir sahifadagi yozuvlar soni (odatda 10-50), va sahifa raqami yoki kursor — to'plamdagi joriy pozitsiyani ko'rsatuvchi belgi. Sahifa hajmini tanlash ma'lumot turiga bog'liq: ixcham elementlar (nomlar) uchun 20-30 yetarli, rasmlar bilan kartalar uchun — 10-15.
Mobil qurilmalar cheklangan resurslarga ega: operativ xotira hajmi, protsessor tezligi va trafik limitlari. Paginatsiya uchta asosiy muammoni hal qiladi: xotira sarfini kamaytirish (xotirada faqat ko'rinadigan elementlar saqlanadi), birinchi ko'rsatishni tezlashtirish (birinchi qism butun to'plamdan tezroq yuklanadi) va trafikni tejash (ma'lumotlar faqat foydalanuvchi ro'yxatni aylantirganda yuklanadi).
Har biri o'ziga xos vazifalarni hal qiluvchi to'rtta asosiy paginatsiya turi mavjud. Usulni tanlash ma'lumotlar izchilligi talablariga, API arxitekturasiga, saqlash turiga va mijoz va server tomonida ruxsat etilgan qo'llash murakkabligiga bog'liq.
| Tur | Ishlash prinsipi | Barqarorlik | Katta hajmlarda tezlik |
|---|---|---|---|
| Offset | SQL da LIMIT + OFFSET | past | OFFSET oshishi bilan kamayadi |
| Cursor | WHERE id > last_id | yuqori | barqaror (O(log n)) |
| Keyset | WHERE key > last_key | yuqori | barqaror (O(log n)) |
| Time-based | WHERE created_at < last_time | o'rta | indeks bilan barqaror |
Offset paginatsiyasi sodda qo'llash muhim bo'lgan statik yoki kamdan-kam yangilanadigan ma'lumotlar to'plamlari uchun mos keladi. Cursor va Keyset — tez-tez qo'shiladigan dinamik ma'lumotlar uchun. Time-based — yozuvlar yaratilish vaqti bo'yicha tartiblangan xronologik lentalar uchun. GraphQL standarti Relay yagona tavsiya etilgan usul sifatida cursor paginatsiyasidan foydalanadi.
Offset paginatsiyasi — sahifama-sahifa yuklashning eng sodda turi. Mijoz page va limit (yoki offset va limit) parametrlarini uzatadi, server SQL OFFSET va LIMIT ni qo'llaydi. Masalan, page=2, limit=20 21 dan 40 gacha yozuvlarni qaytaradi. Bu usul intuitiv tushunarli va har qanday texnologik stackda oson qo'llaniladi.
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items")
async def get_items(
page: int = Query(default=1, ge=1),
limit: int = Query(default=20, le=100)
):
offset = (page - 1) * limit
items = await fetch_items(offset, limit)
total = await count_items()
return {
"items": items,
"total": total,
"page": page,
"pages": (total + limit - 1) // limit
}
Offset paginatsiyasining asosiy kamchiligi — o'tkazib yuborilgan va takrorlanadigan yozuvlar muammosi. Ikki so'rov orasida jadvalga yangi yozuvlar qo'shilsa, OFFSET siljiydi: foydalanuvchi bir yozuvni ikki marta ko'rishi yoki yangisini o'tkazib yuborishi mumkin. Bu izchillik muhim bo'lgan yangiliklar lentalari va chatlar uchun kritikdir.
Boshqa muammo — katta OFFSET larda unumdorlikning pasayishi. Ma'lumotlar bazasi natijani qaytarishdan oldin birinchi offset yozuvlarni skanerdan o'tkazib o'tishi kerak. offset=100000 da hatto LIMIT 20 bilan ham server sezilarli vaqt sarflaydi. PostgreSQL va MySQL OFFSET oshishi bilan tezlikning chiziqli pasayishini ko'rsatadi.
Offset paginatsiyasi quyidagilar uchun eng yaxshi tanlov bo'lib qoladi: ma'muriy panellar (ma'lumotlar kamdan-kam o'zgaradi, sahifalar bo'yicha navigatsiya kerak), hisobotlar va tarixiy jurnallar (barqaror ma'lumot kesimi), filtrlash bilan kataloglar (istalgan sahifaga o'tish mumkin). Offset mijoz tomonida qo'llash eng oson — RecyclerView Paging 3 bilan uni qutidan chiqqandek qo'llab-quvvatlaydi.
Keyset paginatsiyasi yozuvlarni filtrlash uchun noyob kalit (odatda asosiy kalit) dan foydalanadi. OFFSET o'rniga so'rov WHERE id > last_seen_id dan foydalanadi. Bu yozuvlar sonidan qat'iy nazar barqaror unumdorlikni va qo'shishlarda dublikatlarning yo'qligini ta'minlaydi, chunki yangi yozuvlar har doim katta id ga ega.
-- Offset-paginatsiya (muammoli)
SELECT * FROM posts
ORDER BY id
LIMIT 20 OFFSET 100;
-- Keyset-paginatsiya (barqaror)
SELECT * FROM posts
WHERE id > 100
ORDER BY id
LIMIT 20;
Time-based paginatsiyasi (yoki vaqt kursori) navigatsiya uchun created_at vaqt belgisidan foydalanadi. Mijoz oxirgi yuklangan yozuvning timestamp ini uzatadi, server bu belgidan oldin yoki keyin yaratilgan yozuvlarni qaytaradi. Usul ijtimoiy tarmoqlar va yangiliklar lentalarida mashhur, bu erda yozuvlar tartibi nashr vaqti bilan belgilanadi.
Time-based paginatsiyasining xususiyati — ikki yozuv bir millisekundda yaratilganda dublikatlar mumkin. Bu muammoni bartaraf etish uchun time-based kalit noyob id bilan birlashtiriladi: WHERE (created_at, id) < (last_time, last_id). Bunday murakkab kursor har bir yozuvning noyobligini va aniq tartibini kafolatlaydi.
Keyset paginatsiyasi noyob va monoton o'sib boruvchi qiymatga ega ustunni talab qiladi (avto-increment id, UUID v7). Time-based created_at bo'lgan har qanday jadval uchun mos, ammo dublikatlarni qo'shimcha qayta ishlashni talab qiladi. Asosiy farq: Keyset har qanday qo'shish operatsiyalarida barqaror ishlaydi, Time-based esa bir xil vaqt belgilariga sezgir.
Paginatsiya turini tanlash ma'lumotlarning xarakteriga va foydalanuvchi tajribasi talablariga bog'liq. Quyida mobil rivojlanishdagi odatiy stsenariylar uchun tavsiyalar keltirilgan. Universal yechim mavjud emas — har bir usulning optimal bo'lgan qo'llanish sohasi bor.
Android Paging 3 kutubxonasi PagingSource orqali barcha paginatsiya turlarini qo'llab-quvvatlaydi. Offset uchun — Int kaliti (page) bilan PagingSource, Cursor uchun — String yoki Long kaliti (cursor) bilan. PagingSource avtomatik ravishda yuklashni, keshlashni va xatolarda qayta urinishlarni boshqaradi.
class PostPagingSource(
private val api: PostApi
) : PagingSource<Long, Post>() {
override suspend fun load(
params: LoadParams<Long>
): LoadResult<Long, Post> {
val cursor = params.key ?: Long.MAX_VALUE
return try {
val response = api.getPosts(cursor, params.loadSize)
LoadResult.Page(
data = response.items,
prevKey = null,
nextKey = response.items.lastOrNull()?.id
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
override fun getRefreshKey(state: PagingState<Long, Post>): Long? {
return state.anchorPosition?.let {
state.closestItemToPosition(it)?.id
}
}
}
Sahifa hajmi yuklash tezligiga va unumdorlikni idrok etishga ta'sir qiladi. Mobil ilovalar uchun optimal diapazon sahifada 10-25 element. 10 dan kam — API ga juda tez-tez so'rovlar va sakrashli skroll. 25 dan ko'p — sekin tarmoqlarda birinchi qismning uzoq yuklanishi.
Rasmlar va videolar uchun sahifa hajmi 5-10 gacha kamaytiriladi, chunki har bir element media yuklash uchun qo'shimcha vaqt talab qiladi. Matn elementlari (sharhlar, jurnallar) bilan ro'yxatlar uchun hajmi 30-50 yozuvgacha oshirilishi mumkin. Sahifa hajmini API orqali sozlanishi tavsiya etiladi, shunda mijoz turli tarmoq sharoitlariga moslasha oladi.
Ko'p beriladigan savollar
Paginatsiya — ma'lumotlarning hammasini birdan emas, balki qismlarga bo'lib yuklashdir. Kitobdagi kabi: bir sahifani o'qiysiz, keyin keyingisiga o'tasiz. Ilovada bu ro'yxatni aylantirganda keyingi ma'lumot qismi yuklanadi, butun ro'yxat birdan emas, bu trafik va xotirani tejaydi.
Offset yozuvlarni sanaydi: “20 ni o'tkazib yubor, keyingi 10 ni qaytar”. Yuklashlar orasida yangi yozuv qo'shilsa — raqamlash siljiydi. Cursor oxirgi yozuvning noyob identifikatoridan foydalanadi: “ID = 100 dan keyin 10 yozuvni qaytar”. Yangi yozuvlar pozitsiyaga ta'sir qilmaydi.
Mobil ilovalar uchun optimal 10-25 element. Rasmlar bilan ro'yxatlar uchun — 5-10, matn lentalari uchun — 20-30. Hajmi bitta elementning o'rtacha hajmiga bog'liq: element qanchalik og'ir bo'lsa, tez ko'rsatish uchun sahifa shunchalik kichik bo'lishi kerak.
Android Jetpack dan Paging 3 kutubxonasidan foydalaning. U yuklash uchun PagingSource, reaktiv oqim uchun PagingData va aylantirishda avtomatik yuklash uchun PagingDataAdapter ni taqdim etadi. Kutubxona Offset, Cursor va Keyset paginatsiyasini moslashtirilgan PagingSource orqali qo'llab-quvvatlaydi.
Cheksiz skroll — ro'yxat oxiriga yaqinlashganda yangi ma'lumot qismi avtomatik yuklanadigan UI namunasi. Paginatsiya — ma'lumotlarni qismlarga bo'lib yuklash mexanizmi, cheksiz skroll esa uni ko'rsatish usullaridan biri. Alternativ “Ko'proq yuklash” tugmasi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.