التمرير اللانهائي (Infinite Scroll) هو تقنية تحميل المحتوى تلقائياً عند وصول المستخدم إلى نهاية القائمة الحالية. وفقًا لـ UX Design Collective, 2024، يزيد Infinite Scroll من وقت الجلسة في شبكات التواصل الاجتماعي بنسبة 40–60% مقارنة بالترقيم. في تطوير التطبيقات المحمولة، تتم تنفيذ هذه التقنية من خلال مزيج من scroll listeners وطلبات API مع ترقيم قائم على المؤشر (cursor-based pagination). أصبح التمرير اللانهائي المعيار الواقعي لتدفقات المحتوى، ولكنه يتطلب تنفيذًا دقيقًا لتجنب مشاكل الأداء والتنقل.
النقاط الرئيسية
التمرير اللانهائي (Infinite Scroll) هو نمط تحميل بيانات حيث تتم إضافة عناصر جديدة تلقائياً إلى نهاية القائمة أثناء تمرير المستخدم. لا ينقر المستخدم على أزرار «التالي» أو «تحميل المزيد» — يحدد النظام نفسه موعد طلب الدفعة التالية من البيانات ويدرج بسلاسة إدخالات جديدة في القائمة الموجودة.
اكتسب Infinite Scroll شعبية بفضل شبكات التواصل الاجتماعي — تستخدمه Twitter، Instagram و TikTok كآلية توصيل المحتوى الرئيسية. وفقًا لـ Nielsen Norman Group (2024)، يزيد التمرير اللانهائي من المشاركة بنسبة 30–50% لتطبيقات المحتوى لأنه يقلل العبء المعرفي: لا يحتاج المستخدم إلى اتخاذ قرار بالانتقال إلى الصفحة التالية. ولكن بالنسبة للمهام التي تتطلب تنقلًا دقيقًا (البحث، مقارنة المنتجات)، قد يقلل التمرير اللانهائي من الكفاءة.
تقنياً، يتكون التمرير اللانهائي من ثلاثة مكونات: scroll listener (يتبع موقع التمرير)، threshold (المسافة إلى نهاية القائمة لتحفيز التحميل) و آلية الترقيم (طلب API وإدراج البيانات). يعتبر تكوين threshold الصحيح أمرًا حاسمًا: إذا كان المحفز مبكرًا جدًا (1000 بكسل من النهاية)، سيتلقى المستخدم طلبات غير ضرورية؛ إذا كان متأخرًا جدًا (50 بكسل)، سيلاحظ المستخدم توقفًا في التحميل.
تبنى معمارية التمرير اللانهائي على نموذج قائم على الأحداث: يولّد مكون القائمة حدثًا عند الوصول إلى عتبة التمرير، يقوم ViewModel بمعالجته ويستدعي المستودع لتحميل الدفعة التالية من البيانات. بعد استلام الرد، تتم إضافة عناصر جديدة إلى القائمة ويتم تحديث واجهة المستخدم من خلال المكيف (adapter). يجب أن تكون هذه السلسلة غير متزامنة وألا تحجب خيط واجهة المستخدم.
يتضمن الخوارزمية الأساسية للتمرير اللانهائي أربع خطوات. التهيئة: عند فتح الشاشة لأول مرة، يتم تحميل الدفعة الأولى من البيانات (الصفحة 1 أو cursor = null). التتبّع: يتحقّق scroll listener من ما إذا كان المستخدم قد وصل إلى العتبة — عادة ما يكون 200–500 بكسل من نهاية القائمة. التحميل: يتم إرسال طلب إلى API مع معلمات الترقيم، يتم عرض مؤشر التحميل (دولاب في التذييل) على واجهة المستخدم. الإدراج: تتم إضافة عناصر جديدة إلى المكيف، يتم ضبط موقع التمرير لتجنب القفز.
أحد الجوانب الحاسمة هو debounce الطلبات. إذا قام المستخدم بالتمرير بسرعة إلى النهاية، قد ينطلق المحفز عدة مرات قبل تلقي الرد من الخادم. بدون debounce، يؤدي هذا إلى طلبات مكررة (حالة تسابق). الحل هو حجب الطلبات الجديدة حتى يكتمل الطلب السابق. يمنع علم isLoading في ViewModel الاستدعاءات المتعددة: تعيين isLoading = true عند إرسال الطلب، إعادة التعيين عند استلام الرد أو الخطأ.
في المنصات المحمولة، تتم استخدام آليات متخصصة للتمرير اللانهائي. في iOS، يتم استخدام prefetchDataSource في UICollectionView، والذي يطلب تلقائياً بيانات للخلايا خارج الشاشة. في Android، يتم استخدام Paging 3 Library من Google، والتي توفر معمارية جاهزة مع PagingSource، PagingData و PagingDataAdapter. يدعم Paging 3 RemoteMediator للجمع بين بيانات الشبكة والبيانات المحلية ويدير حالة التحميل تلقائياً.
الترقيم القائم على الإزاحة (offset-based) يستخدم معلمات الصفحة والحجم: page=2, size=20 يعيد السجلات 21–40. هذا النهج بسيط في التنفيذ ولكن له مشكلة أساسية — إذا تمت إضافة أو حذف سجلات من قاعدة البيانات بين الطلبات، يختل الإزاحة (يرى المستخدم مكررات أو فجوات). بالنسبة للتدفقات ذات التردد العالي من التغييرات (الأخبار، التعليقات)، ينتج الترقيم القائم على الإزاحة نتائج غير صحيحة.
الترقيم القائم على المؤشر (cursor-based) يستخدم معرفاً فريدًا للعنصر الأخير (cursor): after=id_12345&limit=20. يعيد الخادم 20 سجلًا بعد المؤشر المحدد. يضمن هذا النهج اتساق البيانات بغض النظر عن الإدراجات والعمليات. وفقًا لـ GraphQL Best Practices (2024)، يوصى بالترقيم القائم على المؤشر لجميع تطبيقات الوقت الفعلي حيث تتغير البيانات بشكل ديناميكي.
يعتمد اختيار النهج على نوع التطبيق. لـ شبكات التواصل الاجتماعي (Instagram، TikTok) — فقط القائم على المؤشر، لأن التدفق يتحدث بشكل مستمر. لـ الكتالوجات ذات التغييرات نادرة (فئات منتجات المتاجر الإلكترونية)، يكون الترقيم القائم على الإزاحة مقبولاً. للسيناريوهات الهيجينة، يوصي Google بـ Paging 3 RemoteMediator، الذي يجمع بين الترقيم القائم على المؤشر من الشبكة والترقيم القائم على الإزاحة من قاعدة بيانات Room المحلية.
في Android، النهج القياسي هو مكتبة Paging 3 من Jetpack. يحدد PagingSource مصدر البيانات (الشبكة أو قاعدة البيانات)، يحتوي PagingData على كتل البيانات، ويعرضها PagingDataAdapter في RecyclerView. يدير Paging 3 تلقائياً مسافة التحميل المسبق، إعادة المحاولة والتحديث. لتكامل الشبكة، يتم استخدام RemoteMediator: يقوم بتحميل البيانات من API، يحفظها في Room، ويخبر PagingSource بالتحديثات. وفقًا لـ Google I/O 2024، أكثر من 60% من تطبيقات Android التي تستخدم التمرير اللانهائي تستخدم Paging 3.
مثال على تنفيذ Paging 3 الأساسي:
class FeedPagingSource(
private val api: FeedApi
) : PagingSource<String, Post>() {
override suspend fun load(
params: LoadParams<String>
): LoadResult<String, Post> {
val response = api.getFeed(
cursor = params.key,
limit = params.loadSize
)
return LoadResult.Page(
data = response.items,
prevKey = null,
nextKey = response.nextCursor
)
}
}
في iOS، يتم تنفيذ التمرير اللانهائي باستخدام UICollectionView مع prefetchDataSource. يحتوي بروتوكول UICollectionViewDataSourcePrefetching على طريقة collectionView(_:prefetchItemsAt:)، والتي يتم استدعاؤها عندما يتوقع النظام التمرير إلى مسارات index معينة. بخلاف Android Paging 3، ليس في iOS مكتبة ترقيم مضمنة — يقوم المطورون بتنفيذها يدوياً أو يستخدمون حلولاً خارجية مثل RxSwift + NSLayoutConstraint أو خطوط أنابيب قائمة على Combine.
مثال على التحميل المسبق في iOS:
extension FeedViewController: UICollectionViewDataSourcePrefetching {
func collectionView(
_ collectionView: UICollectionView,
prefetchItemsAt indexPaths: [IndexPath]
) {
let lastRow = collectionView.numberOfItems(inSection: 0) - 1
if indexPaths.contains(IndexPath(row: lastRow, section: 0)) {
viewModel.loadNextPage()
}
}
}
يوفر SwiftUI نهجًا أكثر تصريحية من خلال معدّل onAppear. يضع المطور ProgressView في نهاية القائمة وعند ظهوره، يحفز تحميل الصفحة التالية. وفقًا لـ Apple WWDC 2024، تبسط واجهات API الجديدة AsyncSequence و Swift Algorithms تنفيذ التمرير اللانهائي من خلال توفير عوامل chunking و debounce مضمنة.
المشكلة الرئيسية في تجربة المستخدم للتمرير اللانهائي هي فقدان التذييل والتنقل. في المتاجر الإلكترونية، كثيراً ما يرغب المستخدمون في الذهاب إلى التذييل للحصول على جهات الاتصال أو الروابط. يجعل التمرير اللانهائي التذييل غير قابل للوصول — يتحرك باستمرار إلى الأسفل عندما يتم تحميل المزيد من المحتوى. الحل هو إضافة زر عام عائم (FAB) للتمرير السريع إلى الأعلى أو تثبيت التذييل بشكل منفصل عن القائمة.
المشكلة الثانية هي عدم وجود سجل تمرير. إذا رأى المستخدم منتجًا مهمًا في الموقع 3، تمرر إلى الموقع 50، ثم ضغط على «رجوع» — يعود إلى أعلى القائمة ويضطر إلى التمرير مرة أخرى إلى الموقع 50. الحل هو حفظ موقع التمرير في ViewModel أو استخدام استعادة الحالة على مستوى Activity/UIViewController. يدعم iOS NSUserActivity لاستعادة الموقع، يدعم Android onSaveInstanceState.
المشكلة الثالثة هي الأداء مع آلاف العناصر. إذا لم يتم تكوين الافتراضية، بعد 500–1000 عنصر محمل، يبدأ التطبيق في التباطء بسبب زيادة استهلاك الذاكرة. الحل هو استخدام الافتراضية مع RecyclerView أو UICollectionView، والتي تحتفظ في الذاكرة فقط بالخلايا المرئية والمحملة مسبقًا. كما أن التنظيف الدوري للبيانات القديمة (تجاوز الصفحات بعد N صفحة) يقلل من الحمل.
الأسئلة الشائعة
التمرير اللانهائي (Infinite Scroll) هو تقنية لتحميل المحتوى تلقائياً عند وصول المستخدم إلى أسفل القائمة. يتم إضافة بيانات جديدة بسلاسة دون الحاجة إلى النقر على أزرار الترقيم. يستخدم في شبكات التواصل الاجتماعي، خلاصات الأخبار والكتالوجات ذات المحتوى الديناميكي.
الترقيم يتطلب التنقل اليدوي بين الصفحات (أزرار «1, 2, 3»)، بينما يقوم Infinite Scroll بتحميل البيانات تلقائياً. الترقيم قابل للتوقع ويحافظ على سياق التنقل؛ يزيد Infinite Scroll من المشاركة ولكنه يعقد الوصول إلى التذييل وسجل التمرير. يعتمد الاختيار على نوع المحتوى وأهداف التطبيق.
في Android، المكتبة الموصى بها هي Paging 3 من Jetpack. توفر PagingSource لمصدر البيانات، PagingData للكتل و PagingDataAdapter لـ RecyclerView. تدير Paging 3 تلقائياً التحميل المسبق، حالة التحميل وإعادة المحاولة. للسيناريوهات الهيجينة غير المتصلة/المتصلة، استخدم RemoteMediator.
يتم منع الطلبات المكررة من خلال علم debounce isLoading. عند إرسال الطلب الأول، يتم تعيين العلم على true ويحجب الاستدعاءات الجديدة حتى يتم تلقي الرد. بعد الرد الناجح، يتم إعادة تعيين العلم. بالإضافة، يمكنك إلغاء الكوروتينات (Kotlin) أو Cancellable (Swift) عند التمرير إلى الخلف.
التمرير اللانهائي غير مناسب للتجارة الإلكترونية مع البحث عن المنتجات ومقارنتها، للتطبيقات ذات التذييل المهم (جهات الاتصال، الروابط)، لصفحات نتائج البحث (يحتاج المستخدم إلى العودة إلى عنصر محدد) ولصفحات الإحصائيات/التقارير حيث يهم العدد الإجمالي. في هذه الحالات، استخدم الترقيم الكلاسيكي أو زر «تحميل المزيد».
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.