پیجینیشن ڈیٹا کو صفحہ بہ صفحہ لوڈ کرنے کی ایک تکنیک ہے، جو موبائل ایپلیکیشنز اور ویب سروسز میں بڑے ریکارڈ سیٹ کے ساتھ کام کرنے کے لیے استعمال ہوتی ہے۔ Android Developers Documentation (2025) کے مطابق، پیجینیشن کا درست نفاذ API کے بوجھ کو کم کرتا ہے، ٹریفک بچاتا ہے اور صارف کے تجربے کو بہتر بناتا ہے۔ صفحہ بہ صفحہ لوڈنگ ایپلیکیشن کو تمام ڈیٹا کے لوڈ ہونے کا انتظار کیے بغیر مواد کو بتدریج دکھانے کی اجازت دیتی ہے۔
اہم نکات
پیجینیشن (لاطینی pagination — صفحہ کی تقسیم) ایک تکنیک ہے جو ڈیٹا کے بڑے سیٹ کو ترتیب وار حصوں (صفحات) میں تقسیم کرتی ہے۔ موبائل ایپلیکیشنز میں، پیجینیشن پیغامات کی فہرستوں، نیوز فیڈز، پروڈکٹ کیٹلاگ، آرڈر کی تاریخ اور ممکنہ طور پر لامحدود تعداد میں ریکارڈ والے کسی بھی مجموعے کو لوڈ کرتے وقت استعمال ہوتی ہے۔
پیجینیشن کے بغیر، ایپلیکیشن کو تمام ڈیٹا ایک ساتھ لوڈ کرنے پر مجبور ہونا پڑتا ہے، جس کے نتیجے میں طویل انتظار، زیادہ ٹریفک استعمال اور کمزور آلات پر غیر مستحکم کارکردگی ہوتی ہے۔ پیجینیشن کے ساتھ API درخواست ڈیٹا کا صرف ایک حصہ اور اگلا حصہ لوڈ کرنے کے لیے میٹا معلومات لوٹاتی ہے — اس طرح، ایپلیکیشن موصول ہونے والی معلومات کی مقدار کو کنٹرول کرتی ہے۔
پیجینیشن کی اہم میٹرکس: صفحہ کا سائز (page size) — ایک صفحہ پر ریکارڈ کی تعداد (عام طور پر 10–50)، اور صفحہ نمبر یا کرسر — سیٹ میں موجودہ مقام کا اشارہ۔ صفحہ کے سائز کا انتخاب ڈیٹا کی قسم پر منحصر ہے: کمپیکٹ عناصر (نام) کے لیے 20–30 کافی ہیں، تصاویر والے کارڈز کے لیے 10–15۔
موبائل آلات میں محدود وسائل ہوتے ہیں: RAM، پروسیسر کی رفتار اور ٹریفک کی حدود۔ پیجینیشن تین اہم کام حل کرتی ہے: میموری کی کھپت میں کمی (صرف نظر آنے والے عناصر میموری میں محفوظ ہوتے ہیں)، پہلی نمائش میں تیزی (پہلا حصہ پورے سیٹ کے مقابلے میں تیزی سے لوڈ ہوتا ہے)، اور ٹریفک کی بچت (ڈیٹا صرف اس وقت لوڈ ہوتا ہے جب صارف فہرست کو اسکرول کرتا ہے)۔
پیجینیشن کی چار اہم اقسام ہیں، ہر ایک مخصوص کام حل کرتی ہے۔ طریقہ کار کا انتخاب ڈیٹا کی مستقل مزاجی کی ضروریات، API فن تعمیر، ذخیرہ کی قسم اور کلائنٹ اور سرور پر نفاذ کی قابل قبول پیچیدگی پر منحصر ہے۔
| قسم | کام کرنے کا اصول | استحکام | بڑی مقدار پر رفتار |
|---|---|---|---|
| Offset | SQL میں LIMIT + OFFSET | کم | OFFSET بڑھنے کے ساتھ گھٹتی ہے |
| Cursor | WHERE id > last_id | اعلی | مستحکم (O(log n)) |
| Keyset | WHERE key > last_key | اعلی | مستحکم (O(log n)) |
| Time-based | WHERE created_at < last_time | درمیانی | انڈیکس کے ساتھ مستحکم |
Offset پیجینیشن جامد یا شاذ و نادر ہی اپ ڈیٹ ہونے والے ڈیٹا سیٹ کے لیے موزوں ہے، جب سادہ نفاذ اہم ہو۔ Cursor اور Keyset بار بار اندراجات والے متحرک ڈیٹا کے لیے ہیں۔ Time-based زمانی ترتیب والی فیڈز کے لیے ہے جہاں ریکارڈ تخلیق کے وقت کے مطابق ترتیب دیے جاتے ہیں۔ GraphQL معیار Relay واحد تجویز کردہ طریقہ کے طور پر کرسر پیجینیشن استعمال کرتا ہے۔
Offset پیجینیشن صفحہ پر مبنی لوڈنگ کی سب سے آسان قسم ہے۔ کلائنٹ page اور limit (یا offset اور limit) پیرامیٹرز بھیجتا ہے اور سرور SQL OFFSET اور LIMIT کا اطلاق کرتا ہے۔ مثال کے طور پر، page=2, limit=20 ریکارڈ 21 سے 40 لوٹاتا ہے۔ یہ طریقہ بدیہی ہے اور کسی بھی اسٹیک پر لاگو کرنا آسان ہے۔
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 پیجینیشن کا بنیادی نقصان کھوئے ہوئے اور ڈپلیکیٹ ریکارڈ کا مسئلہ ہے۔ اگر دو درخواستوں کے درمیان جدول میں نئے ریکارڈ شامل کیے جائیں، تو OFFSET منتقل ہو جاتا ہے: صارف ایک ہی ریکارڈ کو دو بار دیکھ سکتا ہے یا نیا ریکارڈ کھو سکتا ہے۔ یہ نیوز فیڈز اور چیٹس کے لیے اہم ہے جہاں مستقل مزاجی اہم ہے۔
دوسرا مسئلہ بڑی OFFSET اقدار پر کارکردگی کا بگاڑ ہے۔ ڈیٹا بیس کو نتیجہ لوٹانے سے پہلے پہلے offset ریکارڈ کو اسکین اور چھوڑنا ہوتا ہے۔ offset=100000 پر LIMIT 20 کے ساتھ بھی، سرور اسکین کرنے میں قابل ذکر وقت گزارے گا۔ PostgreSQL اور MySQL OFFSET بڑھنے کے ساتھ رفتار میں خطی کمی دکھاتے ہیں۔
Offset پیجینیشن اس کے لیے بہترین انتخاب ہے: انتظامی پینل (ڈیٹا شاذ و نادر ہی تبدیل ہوتا ہے، صفحہ کی نیویگیشن ضروری ہے)، رپورٹس اور تاریخی لاگز (ڈیٹا کا مقررہ سنیپ شاٹ)، فلٹر والے کیٹلاگ (کسی بھی صفحے پر جا سکتے ہیں)۔ Offset کلائنٹ پر لاگو کرنا بھی سب سے آسان ہے — RecyclerView Paging 3 کے ساتھ اسے باکس سے باہر سپورٹ کرتا ہے۔
Keyset پیجینیشن ریکارڈ کو فلٹر کرنے کے لیے ایک منفرد کلید (عام طور پر بنیادی کلید) استعمال کرتا ہے۔ OFFSET کے بجائے، سوال WHERE id > last_seen_id استعمال کرتا ہے۔ یہ ریکارڈ کی تعداد سے آزاد مستحکم کارکردگی اور اندراج پر کوئی ڈپلیکیٹ نہ ہونے کو یقینی بناتا ہے، کیونکہ نئے ریکارڈ میں ہمیشہ بڑا id ہوتا ہے۔
-- Offset-پگنیشن (مسئلہ والی)
SELECT * FROM posts
ORDER BY id
LIMIT 20 OFFSET 100;
-- Keyset-پگنیشن (مستحکم)
SELECT * FROM posts
WHERE id > 100
ORDER BY id
LIMIT 20;
Time-based پیجینیشن (یا وقت کے مطابق کرسر) نیویگیشن کے لیے created_at ٹائم اسٹیمپ استعمال کرتا ہے۔ کلائنٹ آخری لوڈ کردہ ریکارڈ کا ٹائم اسٹیمپ بھیجتا ہے اور سرور اس ٹائم اسٹیمپ سے پہلے یا بعد میں بنائے گئے ریکارڈ لوٹاتا ہے۔ یہ طریقہ سوشل نیٹ ورکس اور نیوز فیڈز میں مقبول ہے جہاں ریکارڈ کی ترتیب اشاعت کے وقت سے متعین ہوتی ہے۔
Time-based پیجینیشن کی ایک خصوصیت — اگر دو ریکارڈ ایک ہی ملی سیکنڈ میں بنائے جائیں تو ڈپلیکیٹ ممکن ہیں۔ اس مسئلے کو ختم کرنے کے لیے، وقت پر مبنی کلید کو منفرد id کے ساتھ ملائیں: WHERE (created_at, id) < (last_time, last_id)۔ اس طرح کا مرکب کرسر ہر ریکارڈ کی انفرادیت اور درست ترتیب کی ضمانت دیتا ہے۔
Keyset پیجینیشن کے لیے ایک منفرد اور یکساں طور پر بڑھتی ہوئی قدر (آٹو انکریمنٹ id، UUID v7) والے کالم کی ضرورت ہے۔ Time-based created transcript والی کسی بھی جدول کے لیے موزوں ہے لیکن اس کے لیے اضافی ڈپلیکیٹ ہینڈلنگ کی ضرورت ہے۔ بنیادی فرق: Keyset کسی بھی اندراج کارروائی پر مستحکم طور پر کام کرتا ہے، جبکہ Time-based یکساں ٹائم اسٹیمپ کے لیے حساس ہے۔
پیجینیشن کی قسم کا انتخاب ڈیٹا کی نوعیت اور صارف کے تجربے کی ضروریات پر منحصر ہے۔ ذیل میں موبائل ڈیولپمنٹ میں عام منظرناموں کے لیے سفارشات دی گئی ہیں۔ کوئی عالمگیر حل نہیں ہے — ہر طریقہ کا ایک ڈومین ہے جہاں وہ بہترین ہے۔
Android Paging 3 لائبریری PagingSource کے ذریعے پیجینیشن کی تمام اقسام کو سپورٹ کرتی ہے۔ Offset کے لیے — Int کلید (page) والا PagingSource، Cursor کے لیے — String یا Long کلید (cursor) والا۔ PagingSource خود بخود لوڈنگ، کیشنگ اور خرابیوں پر دوبارہ کوشش کا انتظام کرتی ہے۔
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
}
}
}
صفحہ کا سائز لوڈنگ کی رفتار اور کارکردگی کے تصور کو متاثر کرتا ہے۔ موبائل ایپلیکیشنز کے لیے، بہترین حد فی صفحہ 10–25 آئٹم ہے۔ 10 سے کم — API پر بہت زیادہ درخواستیں اور رک کر اسکرول۔ 25 سے زیادہ — سست نیٹ ورکس پر پہلے حصے کی سست لوڈنگ۔
تصاویر اور ویڈیو کے لیے، صفحہ کا سائز 5–10 تک کم کریں، کیونکہ ہر عنصر کو میڈیا لوڈ کرنے میں اضافی وقت لگتا ہے۔ ٹیکسٹ پر مبنی فہرستوں (تبصرے، لاگز) کے لیے، سائز کو 30–50 ریکارڈ تک بڑھایا جا سکتا ہے۔ API کے ذریعے صفحہ کے سائز کو ترتیب پذیر بنانے کی سفارش کی جاتی ہے تاکہ کلائنٹ مختلف نیٹ ورک حالات کے مطابق ڈھل سکے۔
اکثر پوچھے گئے سوالات
پیجینیشن ڈیٹا کو حصوں میں لوڈ کرنا ہے، ایک ساتھ نہیں۔ جیسے ایک کتاب: آپ ایک صفحہ پڑھتے ہیں، پھر اگلے پر جاتے ہیں۔ ایپ میں، اس کا مطلب ہے کہ فہرست کو اسکرول کرتے وقت ڈیٹا کا اگلا بیچ لوڈ ہوتا ہے، پوری فہرست نہیں، جو ٹریفک اور میموری بچاتا ہے۔
Offset ریکارڈ شمار کرتا ہے: «20 چھوڑ دو، اگلے 10 لوٹاؤ»۔ اگر لوڈ کے درمیان نیا ریکارڈ شامل ہو جائے تو نمبر بگڑ جاتا ہے۔ Cursor آخری ریکارڈ کے منفرد شناخت کنندہ کا استعمال کرتا ہے: «ID = 100 کے بعد 10 ریکارڈ لوٹاؤ»۔ نئے ریکارڈ پوزیشن کو متاثر نہیں کرتے۔
موبائل ایپلیکیشنز کے لیے، 10–25 آئٹم بہترین ہے۔ تصاویر والی فہرستوں کے لیے 5–10، ٹیکسٹ فیڈز کے لیے 20–30۔ سائز ہر عنصر کے اوسط سائز پر منحصر ہے: عنصر جتنا بھاری ہوگا، تیز ڈسپلے کے لیے صفحہ اتنا ہی چھوٹا ہونا چاہیے۔
Android Jetpack سے Paging 3 لائبریری استعمال کریں۔ یہ لوڈنگ کے لیے PagingSource، ری ایکٹیو اسٹریمز کے لیے PagingData اور اسکرول کرنے پر خودکار لوڈنگ کے لیے PagingDataAdapter فراہم کرتی ہے۔ لائبریری کسٹم PagingSource کے ذریعے Offset، Cursor اور Keyset پیجینیشن کو سپورٹ کرتی ہے۔
لامتناہی اسکرول ایک UI پیٹرن ہے جس میں فہرست کے آخر کے قریب پہنچنے پر ڈیٹا کا ایک نیا بیچ خود بخود لوڈ ہوتا ہے۔ پیجینیشن طریقہ کار ہے ڈیٹا کو بیچوں میں لوڈ کرنے کا، اور لامتناہی اسکرول اسے دکھانے کا ایک طریقہ ہے۔ متبادل «مزید لوڈ کریں» بٹن ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں