মোবাইল ডেভেলপমেন্টে পেজিনেশন — এটি কী, প্রকার ও কাজের নীতি

লেখক: IT Sectr প্রকাশিত: 2026-03-11 পড়ার সময়: 9 মিনিট

পেজিনেশন হলো ডেটা পৃষ্ঠায় পৃষ্ঠায় লোড করার একটি কৌশল, যা মোবাইল অ্যাপ্লিকেশন এবং ওয়েব সার্ভিসে বড় রেকর্ড সেট নিয়ে কাজ করতে ব্যবহৃত হয়। Android Developers Documentation (2025)-এর মতে, পেজিনেশনের সঠিক বাস্তবায়ন API-এর লোড কমায়, ট্রাফিক বাঁচায় এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করে। পৃষ্ঠা ধরে লোডিং অ্যাপ্লিকেশনকে সব ডেটা লোড হওয়ার অপেক্ষা না করে ধীরে ধীরে কন্টেন্ট দেখাতে দেয়।

মূল বিষয়

  • পেজিনেশন — পারফরম্যান্স ও ট্রাফিক অপ্টিমাইজ করতে বড় ডেটাসেট অংশে লোড করার পদ্ধতি।
  • Offset পেজিনেশন নেভিগেশনের জন্য অফসেট (page/offset) ব্যবহার করে — সহজ কিন্তু ঘন ঘন ইনসার্টে অস্থির।
  • Cursor পেজিনেশন শেষ রেকর্ড থেকে একটি ইউনিক কার্সর ব্যবহার করে — অনুরোধের মধ্যে ডেটা পরিবর্তন হলে স্থিতিশীল।
  • Keyset পেজিনেশন ইউনিক ইনডেক্সযুক্ত কলাম দিয়ে ফিল্টার করে — ডুপ্লিকেট ছাড়া বড় টেবিলের জন্য কার্যকর।
  • Time-based পেজিনেশন টাইমস্ট্যাম্প অনুযায়ী রেকর্ড গ্রুপ করে — নিউজ ফিড ও সোশ্যাল নেটওয়ার্কের জন্য সুবিধাজনক।

পেজিনেশন কী?

পেজিনেশন (ল্যাটিন pagination — পৃষ্ঠা বিভাজন) একটি কৌশল যা একটি বড় ডেটাসেটকে ক্রমিক অংশে (পৃষ্ঠা) ভাগ করে। মোবাইল অ্যাপ্লিকেশনে, পেজিনেশন ব্যবহার করা হয় বার্তা তালিকা, নিউজ ফিড, পণ্য ক্যাটালগ, অর্ডার ইতিহাস এবং সম্ভাব্য সীমাহীন সংখ্যক রেকর্ডযুক্ত যেকোনো সংগ্রহ লোড করার সময়।

পেজিনেশন ছাড়া, অ্যাপ্লিকেশনকে একসঙ্গে সব ডেটা লোড করতে বাধ্য হতে হয়, যার ফলে দীর্ঘ অপেক্ষা, উচ্চ ট্রাফিক খরচ এবং দুর্বল ডিভাইসে অস্থির পারফরম্যান্স হয়। পেজিনেশনসহ API অনুরোধ ডেটার শুধু একটি অংশ এবং পরবর্তী অংশ লোড করার জন্য মেটা-তথ্য ফেরত দেয় — এইভাবে, অ্যাপ্লিকেশন প্রাপ্ত তথ্যের পরিমাণ নিয়ন্ত্রণ করে।

পেজিনেশনের প্রধান মেট্রিক: পৃষ্ঠার আকার (page size) — একটি পৃষ্ঠায় রেকর্ডের সংখ্যা (সাধারণত 10–50), এবং পৃষ্ঠা নম্বর বা কার্সর — সেটে বর্তমান অবস্থানের নির্দেশক। পৃষ্ঠার আকারের পছন্দ ডেটার প্রকারের উপর নির্ভর করে: কমপ্যাক্ট উপাদানের (নাম) জন্য 20–30 যথেষ্ট, ছবিযুক্ত কার্ডের জন্য — 10–15।

মোবাইল অ্যাপ্লিকেশনে পেজিনেশনের প্রয়োজন কেন

মোবাইল ডিভাইসের সীমিত সম্পদ আছে: র্যাম, প্রসেসরের গতি ও ট্রাফিক সীমা। পেজিনেশন তিনটি মূল কাজ সমাধান করে: মেমরি খরচ কমানো (শুধু দৃশ্যমান উপাদান মেমরিতে সংরক্ষিত হয়), প্রথম প্রদর্শন ত্বরান্বিত করা (প্রথম অংশ পুরো সেটের চেয়ে দ্রুত লোড হয়), এবং ট্রাফিক সাশ্রয় (ব্যবহারকারী তালিকা স্ক্রোল করলেই কেবল ডেটা লোড হয়)।

পেজিনেশনের প্রধান প্রকার

পেজিনেশনের চারটি প্রধান প্রকার আছে, প্রতিটি নির্দিষ্ট কাজ সমাধান করে। পদ্ধতি বাছাই ডেটা সামঞ্জস্যের প্রয়োজনীয়তা, API আর্কিটেকচার, স্টোরেজের ধরন এবং ক্লায়েন্ট ও সার্ভারে বাস্তবায়নের গ্রহণযোগ্য জটিলতার উপর নির্ভর করে।

প্রকারকাজের নীতিস্থিতিশীলতাবড় আয়তনে গতি
OffsetSQL-এ LIMIT + OFFSETনিম্নOFFSET বাড়লে কমে
CursorWHERE id > last_idউচ্চস্থিতিশীল (O(log n))
KeysetWHERE key > last_keyউচ্চস্থিতিশীল (O(log n))
Time-basedWHERE created_at < last_timeমধ্যমইনডেক্সসহ স্থিতিশীল

কখন কোন প্রকার ব্যবহার করবেন

Offset পেজিনেশন স্থির বা খুব কমই আপডেট হওয়া ডেটাসেটের জন্য উপযুক্ত, যখন সরল বাস্তবায়ন গুরুত্বপূর্ণ। Cursor ও Keyset ঘন ঘন ইনসার্টযুক্ত গতিশীল ডেটার জন্য। Time-based কালানুক্রমিক ফিডের জন্য যেখানে রেকর্ড তৈরি সময় অনুযায়ী সাজানো হয়। GraphQL মান Relay একমাত্র প্রস্তাবিত পদ্ধতি হিসেবে কার্সর পেজিনেশন ব্যবহার করে।

Offset পেজিনেশন: সুবিধা ও অসুবিধা

Offset পেজিনেশন পৃষ্ঠা-ভিত্তিক লোডিংয়ের সবচেয়ে সহজ প্রকার। ক্লায়েন্ট page ও limit (বা offset ও limit) প্যারামিটার পাঠায়, এবং সার্ভার SQL OFFSET ও LIMIT প্রয়োগ করে। উদাহরণস্বরূপ, page=2, limit=20 রেকর্ড 21 থেকে 40 ফেরত দেয়। এই পদ্ধতি স্বজ্ঞাত এবং যেকোনো স্ট্যাকে বাস্তবায়ন করা সহজ।

python
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 পেজিনেশন এর জন্য সেরা পছন্দ রয়ে গেছে: প্রশাসনিক প্যানেল (ডেটা খুব কমই পরিবর্তিত হয়, পৃষ্ঠা নেভিগেশন প্রয়োজন), রিপোর্ট ও ঐতিহাসিক লগ (ডেটার নির্দিষ্ট স্ন্যাপশট), ফিল্টারযুক্ত ক্যাটালগ (যেকোনো পৃষ্ঠায় যাওয়া যায়)। Offset ক্লায়েন্টে বাস্তবায়ন করাও সবচেয়ে সহজ — RecyclerView Paging 3-এর সঙ্গে এটি বক্সের বাইরে সমর্থন করে।

Keyset ও Time-based পেজিনেশন

Keyset পেজিনেশন রেকর্ড ফিল্টার করতে একটি ইউনিক কী (সাধারণত প্রাথমিক কী) ব্যবহার করে। OFFSET-এর পরিবর্তে, কোয়েরি WHERE id > last_seen_id ব্যবহার করে। এটি রেকর্ড সংখ্যা নির্বিশেষে স্থিতিশীল পারফরম্যান্স এবং ইনসার্টে কোনো ডুপ্লিকেট না হওয়া নিশ্চিত করে, কারণ নতুন রেকর্ডের id সবসময় বড় হয়

sql
-- 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 পেজিনেশন

Time-based পেজিনেশন (বা সময় অনুযায়ী কার্সর) নেভিগেশনের জন্য created_at টাইমস্ট্যাম্প ব্যবহার করে। ক্লায়েন্ট শেষ লোড করা রেকর্ডের টাইমস্ট্যাম্প পাঠায়, এবং সার্ভার সেই টাইমস্ট্যাম্পের আগে বা পরে তৈরি রেকর্ড ফেরত দেয়। এই পদ্ধতি সোশ্যাল নেটওয়ার্ক ও নিউজ ফিডে জনপ্রিয় যেখানে রেকর্ডের ক্রম প্রকাশনার সময় দ্বারা নির্ধারিত হয়।

Time-based পেজিনেশনের একটি বৈশিষ্ট্য — দুটি রেকর্ড একই মিলিসেকেন্ডে তৈরি হলে ডুপ্লিকেট সম্ভব। এই সমস্যা দূর করতে, একটি ইউনিক id-এর সাথে সময়-ভিত্তিক কী একত্রিত করুন: WHERE (created_at, id) < (last_time, last_id)। এই ধরনের যৌগিক কার্সর প্রতিটি রেকর্ডের স্বতন্ত্রতা এবং সঠিক ক্রম নিশ্চিত করে।

Keyset ও Time-based-এর তুলনা

Keyset পেজিনেশনের জন্য একটি ইউনিক এবং একঘেয়েভাবে বাড়তে থাকা মান (অটো-ইনক্রিমেন্ট id, UUID v7)যুক্ত কলাম প্রয়োজন। Time-based created_atযুক্ত যেকোনো টেবিলের জন্য উপযুক্ত, কিন্তু অতিরিক্ত ডুপ্লিকেট হ্যান্ডলিং প্রয়োজন। প্রধান পার্থক্য: Keyset যেকোনো ইনসার্ট অপারেশনে স্থিতিশীলভাবে কাজ করে, যেখানে Time-based অভিন্ন টাইমস্ট্যাম্পের প্রতি সংবেদনশীল।

প্রকল্পের জন্য পেজিনেশনের প্রকার কীভাবে বেছে নেবেন

পেজিনেশনের প্রকার বাছাই ডেটার প্রকৃতি ও ব্যবহারকারীর অভিজ্ঞতার প্রয়োজনীয়তার উপর নির্ভর করে। নিচে মোবাইল ডেভেলপমেন্টে সাধারণ পরিস্থিতির জন্য সুপারিশ দেওয়া হল। কোনো সার্বজনীন সমাধান নেই — প্রতিটি পদ্ধতির একটি ক্ষেত্র আছে যেখানে তা সর্বোত্তম।

  • চ্যাট / মেসেঞ্জার — Cursor পেজিনেশন (বার্তার id অনুযায়ী)। নতুন বার্তা উপরে যুক্ত হয়, কার্সর নষ্ট হয় না।
  • নিউজ ফিড — Time-based পেজিনেশন (created_at অনুযায়ী)। রেকর্ড সময় অনুযায়ী সাজানো, কালানুক্রম গুরুত্বপূর্ণ।
  • পণ্য ক্যাটালগ — Offset পেজিনেশন। ব্যবহারকারী নির্দিষ্ট পৃষ্ঠায় যেতে পারেন, ডেটা খুব কমই পরিবর্তিত হয়।
  • অর্ডার ইতিহাস — Cursor পেজিনেশন। স্থিতিশীলতা গুরুত্বপূর্ণ কারণ লোডের মধ্যে নতুন অর্ডার যুক্ত হয়।
  • মন্তব্য — Keyset পেজিনেশন। প্রতিটি মন্তব্যের ইউনিক id থাকে, ডুপ্লিকেট ছাড়া বড় আয়তন।

Paging 3-এর সাথে Android-এ বাস্তবায়ন

Android Paging 3 লাইব্রেরি PagingSource-এর মাধ্যমে সব ধরনের পেজিনেশন সমর্থন করে। Offset-এর জন্য — Int কী (page)সহ PagingSource, Cursor-এর জন্য — String বা Long কী (cursor)সহ। PagingSource স্বয়ংক্রিয়ভাবে লোডিং, ক্যাশিং এবং ত্রুটিতে পুনঃচেষ্টা পরিচালনা করে।

kotlin
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 আইটেম। ১০-এর কম — API-তে অত্যধিক অনুরোধ ও থেমে থেমে স্ক্রোল। ২৫-এর বেশি — ধীর নেটওয়ার্কে প্রথম অংশের ধীর লোডিং।

ছবি ও ভিডিওর জন্য, পৃষ্ঠার আকার ৫–১০-এ কমিয়ে দিন, কারণ প্রতিটি উপাদান মিডিয়া লোড করতে অতিরিক্ত সময় নেয়। টেক্সট-ভিত্তিক তালিকার (মন্তব্য, লগ) জন্য, আকার 30–50 রেকর্ড পর্যন্ত বাড়ানো যেতে পারে। API-র মাধ্যমে পৃষ্ঠার আকার কনফিগারযোগ্য করার সুপারিশ করা হয় যাতে ক্লায়েন্ট বিভিন্ন নেটওয়ার্ক অবস্থার সাথে খাপ খাইয়ে নিতে পারে।

সচরাচর জিজ্ঞাসা

সরল ভাষায় পেজিনেশন কী?

পেজিনেশন হলো ডেটা অংশে লোড করা, একসঙ্গে সব না। যেমন বই: আপনি একটি পৃষ্ঠা পড়েন, তারপর পরবর্তীতে যান। অ্যাপে, এর অর্থ হল তালিকা স্ক্রোল করার সময় ডেটার পরবর্তী ব্যাচ লোড হয়, পুরো তালিকা নয়, যা ট্রাফিক ও মেমরি বাঁচায়।

Offset কীভাবে Cursor পেজিনেশন থেকে আলাদা?

Offset রেকর্ড গণনা করে: “20 এড়িয়ে যাও, পরবর্তী 10 ফেরত দাও।” লোডের মধ্যে নতুন রেকর্ড যোগ করলে, সংখ্যা নষ্ট হয়। Cursor শেষ রেকর্ডের ইউনিক শনাক্তকারী ব্যবহার করে: “ID = 100-এর পরে 10 রেকর্ড ফেরত দাও।” নতুন রেকর্ড অবস্থানকে প্রভাবিত করে না।

পেজিনেশনের জন্য সর্বোত্তম পৃষ্ঠার আকার কত?

মোবাইল অ্যাপ্লিকেশনের জন্য, 10–25 আইটেম সর্বোত্তম। ছবিযুক্ত তালিকার জন্য — 5–10, টেক্সট ফিডের জন্য — 20–30। আকার প্রতিটি উপাদানের গড় আকারের উপর নির্ভর করে: উপাদান যত ভারী, দ্রুত প্রদর্শনের জন্য পৃষ্ঠা তত ছোট হওয়া উচিত।

RecyclerView-এ কীভাবে পেজিনেশন বাস্তবায়ন করবেন?

Android Jetpack-এর Paging 3 লাইব্রেরি ব্যবহার করুন। এটি লোডিংয়ের জন্য PagingSource, রিঅ্যাকটিভ স্ট্রিমের জন্য PagingData এবং স্ক্রোলের সময় স্বয়ংক্রিয় লোডিংয়ের জন্য PagingDataAdapter প্রদান করে। লাইব্রেরি কাস্টম PagingSource-এর মাধ্যমে Offset, Cursor ও Keyset পেজিনেশন সমর্থন করে।

ইনফিনিট স্ক্রোল কী এবং এটি পেজিনেশন থেকে কীভাবে আলাদা?

ইনফিনিট স্ক্রোল একটি UI প্যাটার্ন যেখানে তালিকার শেষের কাছে পৌঁছালে ডেটার একটি নতুন ব্যাচ স্বয়ংক্রিয়ভাবে লোড হয়। পেজিনেশন হলো পদ্ধতি ডেটা ব্যাচে লোড করার, আর ইনফিনিট স্ক্রোল তা প্রদর্শনের একটি উপায়। বিকল্প হলো “আরও লোড করুন” বোতাম।

সারাংশ

  • পেজিনেশন — ডেটা অংশে লোড করার কৌশল, যেকোনো ধরনের তালিকার মোবাইল অ্যাপ্লিকেশনের জন্য প্রয়োজনীয়।
  • Offset পেজিনেশন বাস্তবায়ন করা সহজ কিন্তু ইনসার্টে অসামঞ্জস্য এবং বড় OFFSET-এ পারফরম্যান্সের অবনতিতে ভোগে।
  • Cursor পেজিনেশন নেভিগেশনের জন্য ইউনিক শনাক্তকারী ব্যবহার করে — যেকোনো আয়তনে স্থিতিশীল ও কার্যকর।
  • Keyset পেজিনেশন প্রাথমিক কী দিয়ে ফিল্টার করে, ইনডেক্স ব্যবহারের মাধ্যমে সর্বোচ্চ পারফরম্যান্স প্রদান করে।
  • Time-based পেজিনেশন টাইমস্ট্যাম্প অনুযায়ী রেকর্ড গ্রুপ করে — কালানুক্রমিক ফিড ও সোশ্যাল নেটওয়ার্কের জন্য আদর্শ।
  • পদ্ধতি বাছাই ডেটার প্রকৃতির উপর নির্ভর করে: গতিশীলের জন্য — Cursor/Keyset, স্থিরের জন্য — Offset, ফিডের জন্য — Time-based।
  • Paging 3 Android-এ এবং iOS/ওয়েবে স্ট্যান্ডার্ড কার্সর সমাধান যেকোনো ধরনের পেজিনেশনের জন্য প্রস্তুত অবকাঠামো প্রদান করে।

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন