Paginasiya — mobil tətbiqlərdə və veb xidmətlərdə böyük məlumat dəstləri ilə işləmək üçün istifadə olunan səhifə-səhifə məlumat yükləmə texnikası. Android Developers Documentation (2025)-a görə, paginasiyanın düzgün tətbiqi API yükünü azaldır, trafikə qənaət edir və istifadəçi təcrübəsini yaxşılaşdırır. Səhifə-səhifə yükləmə tətbiqə məzmunu tədricən, bütün məlumatların tam yüklənməsini gözləmədən göstərməyə imkan verir.
Əsas məqamlar
Paginasiya (ing. pagination — səhifə bölgüsü) — böyük məlumat dəstini ardıcıl hissələrə (səhifələrə) bölmə texnikasıdır. Mobil tətbiqlərdə paginasiya mesaj siyahılarının, xəbər lentinin, məhsul kataloqlarının, sifariş tarixçəsinin və potensial olaraq limitsiz sayda qeydləri olan digər kolleksiyaların yüklənməsi zamanı istifadə olunur.
Paginasiya olmadan tətbiq bütün məlumatları birdən yükləməli olur ki, bu da uzun gözləməyə, böyük trafik sərfinə və zəif cihazlarda qeyri-sabit işə səbəb olur. Paginasiyalı API sorğusu yalnız bir hissə məlumat və növbəti hissəni yükləmək üçün meta-məlumat qaytarır — beləliklə, tətbiq alınan məlumatın həcminə nəzarət edir.
Paginasiyanın əsas göstəriciləri: səhifə ölçüsü (page size) — bir səhifədəki qeydlərin sayı (adətən 10-50), və səhifə nömrəsi və ya kursor — dəstdəki cari mövqeyi göstərən işarə. Səhifə ölçüsünün seçimi məlumat növündən asılıdır: yığcam elementlər (adlar) üçün 20-30, şəkilli kartlar üçün 10-15 kifayətdir.
Mobil cihazların məhdud resursları var: operativ yaddaşın həcmi, prosessor sürəti və trafik limitləri. Paginasiya üç əsas problemi həll edir: yaddaş istehlakının azaldılması (yaddaşda yalnız görünən elementlər saxlanılır), ilk göstərilmənin sürətləndirilməsi (birinci hissə bütün dəstdən daha tez yüklənir) və trafikə qənaət (məlumatlar yalnız istifadəçi siyahını sürüşdürdükdə yüklənir).
Hər biri spesifik vəzifələri həll edən dörd əsas paginasiya növü mövcuddur. Metodun seçimi məlumatların ardıcıllığı tələblərindən, API arxitekturasından, saxlama növündən və müştəri və server tərəfində icazə verilən tətbiq mürəkkəbliyindən asılıdır.
| Növ | İş prinsipi | Sabitlik | Böyük həcmlərdə sürət |
|---|---|---|---|
| Offset | SQL-də LIMIT + OFFSET | aşağı | OFFSET artdıqca azalır |
| Cursor | WHERE id > last_id | yüksək | sabit (O(log n)) |
| Keyset | WHERE key > last_key | yüksək | sabit (O(log n)) |
| Time-based | WHERE created_at < last_time | orta | indekslə sabit |
Offset paginasiyası sadə tətbiqin vacib olduğu statik və ya nadir hallarda yenilənən məlumat dəstləri üçün uyğundur. Cursor və Keyset — tez-tez əlavələr olan dinamik məlumatlar üçün. Time-based — qeydlərin yaradılma vaxtına görə sıralandığı xronoloji lentlər üçün. GraphQL standartı Relay yeganə tövsiyə olunan metod kimi cursor paginasiyasını istifadə edir.
Offset paginasiyası — səhifə-səhifə yükləmənin ən sadə növüdür. Müştəri page və limit (və ya offset və limit) parametrlərini ötürür, server SQL OFFSET və LIMIT tətbiq edir. Məsələn, page=2, limit=20 21-dən 40-a qədər qeydləri qaytarır. Bu metod intuitiv olaraq başa düşüləndir və istənilən texnoloji yığında asanlıqla tətbiq olunur.
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 paginasiyasının əsas çatışmazlığı — buraxılmış və təkrarlanan qeydlər problemi. İki sorğu arasında cədvələ yeni qeydlər əlavə edilərsə, OFFSET dəyişir: istifadəçi eyni qeydi iki dəfə görə bilər və ya yenisini qaçıra bilər. Bu, ardıcıllığın vacib olduğu xəbər lentləri və çatlar üçün kritikdir.
Digər problem — böyük OFFSET-lərdə performansın azalması. Məlumat bazası nəticəni qaytarmazdan əvvəl ilk offset qeydləri skan edib keçməlidir. offset=100000 olduqda hətta LIMIT 20 ilə belə server skan etməyə nəzərəçarpacaq vaxt sərf edir. PostgreSQL və MySQL OFFSET artdıqca xətti sürət azalması göstərir.
Offset paginasiyası aşağıdakılar üçün ən yaxşı seçim olaraq qalır: inzibati panellər (məlumatlar nadir hallarda dəyişir, səhifələr üzrə naviqasiya lazımdır), hesabatlar və tarixi jurnallar (sabit məlumat kəsimi), filtrləmə ilə kataloqlar (istənilən səhifəyə keçmək olar). Offset həmçinin müştəri tərəfində tətbiq etmək üçün ən asandır — RecyclerView Paging 3 ilə onu qutudan çıxan kimi dəstəkləyir.
Keyset paginasiyası qeydləri filtrləmək üçün unikal açar (adətən əsas açar) istifadə edir. OFFSET əvəzinə sorğu WHERE id > last_seen_id istifadə edir. Bu, qeydlərin sayından asılı olmayaraq sabit performans və əlavələr zamanı dublikatların olmamasını təmin edir, çünki yeni qeydlər həmişə daha böyük id-yə malikdir.
-- Offset səhifələmə (problematik)
SELECT * FROM posts
ORDER BY id
LIMIT 20 OFFSET 100;
-- Keyset səhifələmə (sabit)
SELECT * FROM posts
WHERE id > 100
ORDER BY id
LIMIT 20;
Time-based paginasiyası (və ya zaman kursoru) naviqasiya üçün created_at zaman damğasından istifadə edir. Müştəri son yüklənmiş qeydin timestamp-ni ötürür, server bu damğadan əvvəl və ya sonra yaradılmış qeydləri qaytarır. Metod sosial şəbəkələrdə və xəbər lentlərində populyardır, burada qeydlərin sırası dərc vaxtı ilə müəyyən edilir.
Time-based paginasiyasının xüsusiyyəti — iki qeyd eyni millisaniyədə yaradıldıqda dublikatlar mümkündür. Bu problemi aradan qaldırmaq üçün time-based açar unikal id ilə birləşdirilir: WHERE (created_at, id) < (last_time, last_id). Belə mürəkkəb kursor hər bir qeydin unikallığını və dəqiq sırasını təmin edir.
Keyset paginasiyası unikal və monoton artan dəyəri olan sütun tələb edir (auto-increment id, UUID v7). Time-based created_at olan istənilən cədvəl üçün uyğundur, lakin dublikatların əlavə işlənməsini tələb edir. Əsas fərq: Keyset istənilən əlavə əməliyyatlarında sabit işləyir, Time-based isə eyni zaman damğalarına həssasdır.
Paginasiya növünün seçimi məlumatların xarakterindən və istifadəçi təcrübəsi tələblərindən asılıdır. Aşağıda mobil inkişafda tipik ssenarilər üçün tövsiyələr verilmişdir. Universal həll yoxdur — hər bir metodun optimal olduğu tətbiq sahəsi var.
Android Paging 3 kitabxanası PagingSource vasitəsilə bütün paginasiya növlərini dəstəkləyir. Offset üçün — Int açarı (page) ilə PagingSource, Cursor üçün — String və ya Long açarı (cursor) ilə. PagingSource avtomatik olaraq yükləməni, keşləməni və xətalarda təkrar cəhdləri idarə edir.
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
}
}
}
Səhifə ölçüsü yükləmə sürətinə və performans qavrayışına təsir edir. Mobil tətbiqlər üçün optimal diapazon səhifədə 10-25 elementdir. 10-dan az — API-yə çox tez-tez sorğular və sıçrayışlı skroll. 25-dən çox — yavaş şəbəkələrdə ilk hissənin uzun yüklənməsi.
Şəkillər və videolar üçün səhifə ölçüsü 5-10-a endirilir, çünki hər bir element media yükləmək üçün əlavə vaxt tələb edir. Mətn elementləri olan siyahılar (şərhlər, jurnallar) üçün ölçü 30-50 qeydə qədər artırıla bilər. Səhifə ölçüsünün API vasitəsilə konfiqurasiya edilə bilən olması tövsiyə olunur ki, müştəri müxtəlif şəbəkə şərtlərinə uyğunlaşa bilsin.
Tez-tez verilən suallar
Paginasiya — məlumatların hamısını birdən yox, hissə-hissə yükləməkdir. Kitabda olduğu kimi: bir səhifəni oxuyursan, sonra növbəti səhifəyə keçirsən. Tətbiqdə bu o deməkdir ki, siyahını sürüşdürərkən növbəti məlumat hissəsi yüklənir, bütün siyahı birdən yox, bu da trafikə və yaddaşa qənaət edir.
Offset qeydləri sayır: “20-ni keç, növbəti 10-u qaytar”. Yükləmələr arasında yeni qeyd əlavə olunarsa — nömrələmə sürüşür. Cursor son qeydin unikal identifikatorundan istifadə edir: “ID = 100-dən sonra 10 qeyd qaytar”. Yeni qeydlər mövqeyə təsir etmir.
Mobil tətbiqlər üçün optimal 10-25 elementdir. Şəkilli siyahılar üçün — 5-10, mətn lentləri üçün — 20-30. Ölçü bir elementin orta ölçüsündən asılıdır: element nə qədər ağır olsa, sürətli göstərilmə üçün səhifə bir o qədər kiçik olmalıdır.
Android Jetpack-dən Paging 3 kitabxanasından istifadə edin. O, yükləmə üçün PagingSource, reaktiv axın üçün PagingData və sürüşdürmə zamanı avtomatik yükləmə üçün PagingDataAdapter təqdim edir. Kitabxana Offset, Cursor və Keyset paginasiyasını fərdi PagingSource vasitəsilə dəstəkləyir.
Sonsuz skroll — siyahının sonuna yaxınlaşdıqda yeni məlumat hissəsinin avtomatik yükləndiyi UI nümunəsidir. Paginasiya — məlumatların hissə-hissə yüklənməsi mexanizmidir, sonsuz skroll isə onun göstərilmə üsullarından biridir. Alternativ “Daha çox yüklä” düyməsidir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun