تعلم كيفية بناء قوائم لوحة سريعة مع 100k صف باستخدام الترقيم، التفريغ، فلاتر ذكية واستعلامات مصوغة ليبقى الأداء سريعًا في الأدوات الداخلية.

شاشة القائمة عادةً تبدو مقبولة إلى أن تتوقف عن ذلك. يبدأ المستخدمون بملاحظة تقطعات صغيرة تتراكم: تشويش في التمرير، توقف الصفحة لوهلة بعد كل تحديث، استجابة الفلاتر تستغرق ثوانٍ، وتظهر دارة تحميل بعد كل نقرة. أحيانًا يبدو تبويب المتصفح متجمدًا لأن خيط واجهة المستخدم مشغول.
يُعدّ حجم 100k صف نقطة تحول شائعة لأنه يضغط على كل جزء من النظام مرة واحدة. حجم البيانات لا يزال طبيعيًا لقاعدة بيانات، لكنه كبير بما يكفي لجعل عدم الكفاءات الصغيرة واضحة في المتصفح وعلى الشبكة. إذا حاولت عرض كل شيء دفعة واحدة، تتحول شاشة بسيطة إلى خط معالجة ثقيل.
الهدف ليس عرض كل الصفوف. الهدف هو مساعدة شخص ما في إيجاد ما يحتاج بسرعة: الخمسين صفًا الصحيحة، الصفحة التالية، أو شريحة ضيقة بناءً على فلتر.
من المفيد تقسيم العمل إلى أربعة أجزاء:
إذا كان أي جزء مكلفًا، ستشعر الشاشة كلها بالبُطء. صندوق بحث بسيط يمكن أن يطلق طلبًا يرتب 100k صف، يعيد آلاف السجلات، ثم يجبر المتصفح على رسمها كلها. هكذا يصبح الكتابة بطيئة.
عندما تبني الفرق أدوات داخلية بسرعة (بما في ذلك عبر منصات برمجة تفاعلية مثل Koder.ai)، تكون شاشات القوائم غالبًا المكان الأول الذي يكشف فيه نمو البيانات الحقيقي الفجوة بين "يعمل على مجموعة بيانات تجريبية" و"يشعر بالسرعة كل يوم".
قبل أن تحسّن، قرر ماذا يعني "سريع" لهذه الشاشة. كثير من الفرق تطارد معدل النقل (تحميل كل شيء) بينما يحتاج المستخدمون بشكل أساسي زمن استجابة منخفض (رؤية شيء يتحدث بسرعة). يمكن أن تبدو القائمة فورية حتى لو لم تُحمّل كل 100k صف، طالما أنها تستجيب بسرعة للتمرير والفرز والفلاتر.
هدف عملي هو زمن الوصول لأول صف، وليس زمن التحميل الكامل. يثق المستخدمون بالصفحة عندما يرون أول 20 إلى 50 صفًا بسرعة وتظل التداخلات سلسة.
اختر مجموعة صغيرة من الأرقام يمكنك تتبعها في كل مرة تغير شيئًا:
COUNT(*) وعمليات SELECT العريضة)هذه القياسات ترتبط بالأعراض الشائعة. إن قفزت CPU في المتصفح عند التمرير، فالواجهة الأمامية تقوم بعمل زائد لكل صف. إن انتظر المستخدم مؤقتًا ثم كان التمرير جيدًا بعد ذلك، فعادة ما تكون المشكلة في الخلفية أو الشبكة. إن كان الطلب سريعًا لكن الصفحة ما تزال تتجمد، فغالبًا السبب هو العرض أو معالجات ثقيلة على جهة العميل.
جرّب تجربة بسيطة: اترك واجهة المستخدم كما هي، لكن قيد الخادم مؤقتًا ليعيد 20 صفًا فقط بنفس الفلاتر. إن أصبحت الواجهة سريعة، فالمعنِق هو حجم التحميل أو وقت الاستعلام. إن بقيت بطيئة، انظر إلى العرض، التنسيق، ومكونات الصفوف.
مثال: شاشة Orders داخلية تبدو بطيئة عند الكتابة في البحث. إذا كانت الـ API تعيد 5,000 صف والمتصفح يفلترها على كل ضغطة مفتاح، ستتأخر الكتابة. إن استغرقت الـ API ثانيتين بسبب استعلام COUNT على فلتر غير مفهرس، سترى الانتظار قبل أي تغيير في الصفوف. إصلاحات مختلفة، نفس شكوى المستخدم.
غالبًا ما يكون المتصفح هو عنق الزجاجة الأول. يمكن أن تبدو القائمة بطيئة حتى لو كانت الـ API سريعة، ببساطة لأن الصفحة تحاول رسم الكثير. القاعدة الأولى بسيطة: لا ترسم آلاف الصفوف في DOM مرة واحدة.
حتى قبل إضافة تفريغ كامل، اجعل كل صف خفيفًا. الصف الذي يحتوي على أغلفة متداخلة، أيقونات، تلميحات أدوات، وأنماط شرطية معقدة في كل خلية يكلفك عند كل تمرير وكل تحديث. فضّل نصًا بسيطًا، بعض الشارات الصغيرة، وعنصرين تفاعليين كحد أقصى في كل صف.
ارتفاع صف ثابت يساعد أكثر مما يبدو. عندما يكون كل صف بنفس الارتفاع، يمكن للمتصفح توقع التخطيط ويظل التمرير سلسًا. الصفوف ذات الارتفاع المتغير (وصف يلتف، ملاحظات قابلة للتوسيع، صور ملف شخصية كبيرة) تُطلق قياسًا إضافيًا وإعادة تدفق. إن احتجت تفاصيل إضافية، فكّر في لوحة جانبية أو منطقة قابلة للتوسيع واحدة، لا صف متعدد الأسطر كامل.
التنسيق أيضًا عبء خفي. التواريخ، العملات، والعمل النصي المكثف يتراكم عندما يتكرر عبر خلايا عديدة.
إن لم يكن القيمة مرئية، فلا تحسبها بعد. خزّن نتائج التنسيق المكلفة واحسبها عند الطلب، مثلاً عندما يصبح الصف مرئيًا أو عندما يفتح المستخدم الصف.
خطوات سريعة تعطي غالبًا تحسّنًا ملحوظًا:
مثال: جدول Invoices داخلي ينسق 12 عمودًا من العملات والتواريخ سيتقطع عند التمرير. حفظ القيم المنسقة لكل فاتورة وتأخير العمل للصفوف خارج الشاشة يمكن أن يجعله يشعر بأنه فوري، حتى قبل عمل أعمق على الخلفية.
التفريغ يعني أن الجدول يرسم فقط الصفوف التي يمكنك رؤيتها فعلًا (مع مخزن صغير أعلاه وأسفله). أثناء التمرير، يعيد استخدام نفس عناصر DOM ويبدّل البيانات داخلها. هذا يمنع المتصفح من محاولة رسم عشرات الآلاف من مكونات الصفوف دفعة واحدة.
التفريغ مناسب عندما يكون لديك قوائم طويلة، جداول عريضة، أو صفوف ثقيلة (صور ملف شخصية، شارات حالة، قوائم إجراءات، تلميحات). كما يفيد عندما يقوم المستخدمون بالتمرير كثيرًا ويتوقعون عرضًا مستمرًا سلسًا بدل القفز صفحة بصفحة.
ليس سحريًا. بعض الأمور تسبب مفاجآت:
النهج الأبسط ممل لكنه عملي: ارتفاع صف ثابت، أعمدة متوقعة، وليس عدد كبير من الأدوات التفاعلية داخل كل صف.
يمكنك الجمع بينهما: استخدم ترقيمًا (أو تحميل المزيد بنهاية الصفحة) لتقييد ما تجلبه من الخادم، واستخدم التفريغ للحفاظ على العرض رخيصًا داخل الشريحة المحمّلة.
نمط عملي هو جلب حجم صفحة عادي (غالبًا 100 إلى 500 صف)، تطبيق التفريغ داخل تلك الصفحة، وتقديم عناصر تحكم واضحة للتنقل بين الصفحات. إن استخدمت التمرير اللانهائي، أضف مؤشرًا مرئيًا "تم تحميل X من Y" حتى يفهم المستخدمون أنهم لا يرون كل شيء بعد.
إن كنت تحتاج شاشة قائمة تبقى قابلة للاستخدام مع نمو البيانات، الترقيم عادةً الخيار الآمن الافتراضي. إنه متوقع، يعمل جيدًا لعمليات الإدارة (مراجعة، تحرير، الموافقة)، ويدعم احتياجات شائعة مثل تصدير "الصفحة 3 بهذه الفلاتر" دون مفاجآت. كثير من الفرق تعود إلى الترقيم بعد تجربة التمرير الأجمل.
التمرير اللانهائي قد يبدو لطيفًا للتصفح العرضي، لكنه يكلفك ضمنيًا: يفقد الناس إحساسهم بالمكان، زر العودة غالبًا لا يعيدهم إلى نفس الموضع، وجلسات طويلة قد تتراكم في الذاكرة مع تحميل المزيد من الصفوف. حل وسط هو زر "تحميل المزيد" الذي لا يزال يستخدم صفحات، لذا يبقى المستخدمون موجهين.
ترقيم التحويل (offset) هو النهج الكلاسيكي page=10&size=50. سهل، لكنه يمكن أن يصبح أبطأ على الجداول الكبيرة لأن قاعدة البيانات قد تضطر لتخطي صفوف كثيرة للوصول لصفحات لاحقة. كما يمكن أن يشعر المستخدم بالغرابة عند وصول صفوف جديدة وتحول العناصر بين الصفحات.
ترقيم المفتاح (المعروف بالـ cursor) يطلب "الخمسون صفًا التالية بعد آخر عنصر شوهد"، عادة باستخدام id أو created_at. يبقى سريعًا لأنه لا يحتاج للعد والتخطي بنفس القدر.
قاعدة عملية:
المستخدمون يحبون رؤية الإجماليات، لكن "عد كل الصفوف المطابقة" قد يكون مكلفًا مع فلاتر معقدة. الخيارات تشمل تخزين العدوصات المشهورة مؤقتًا، تحديث العدّ في الخلفية بعد تحميل الصفحة، أو عرض عدد تقديري (مثل "10,000+").
مثال: شاشة Orders داخلية يمكن أن تظهر النتائج فورًا باستخدام ترقيم keyset، ثم تملأ العدد الدقيق فقط عندما يتوقف المستخدم عن تغيير الفلاتر لثانية.
إذا كنت تبني هذا في Koder.ai، تعامل مع سلوك الترقيم والعد كجزء من مواصفات الشاشة مبكرًا، حتى لا تتصارع الاستعلامات المولدة وحالة الواجهة لاحقًا.
معظم شاشات القوائم تبدو بطيئة لأنها تبدأ واسعة مفتوحة: تحميل كل شيء، ثم تطلب من المستخدم تضييقه. اقلب ذلك. ابدأ بإعدادات افتراضية sinnvoll تُرجع مجموعة صغيرة ومفيدة (مثال: آخر 7 أيام، عنايتي، الحالة: مفتوح)، واجعل خيار "كل الوقت" اختيارًا صريحًا.
بحث النص فخ شائع آخر. إن شغلت استعلامًا على كل ضغطة مفتاح، فإنك تنشئ تراكمًا من الطلبات وواجهة تومض. قم بتأخير إدخال البحث (debounce) حتى تستقر الكتابة قليلًا، وألغِ الطلبات القديمة عندما يبدأ طلب جديد. قاعدة بسيطة: إذا المستخدم لا يزال يكتب، فلا تضرب الخادم بعد.
التصفية تبدو سريعة فقط عندما تكون واضحة أيضًا. أظهر شارات الفلاتر قرب أعلى الجدول ليعرف المستخدمون ما مفعل ويمكن إزالته بنقرة واحدة. اجعل تسميات الشارات بشرية، لا أسماء الحقول الخام (مثال: Owner: Sam بدلًا من owner_id=42). عندما يقول شخص ما "اختفت نتائجي"، فعادةً ما يكون السبب فلتر مخفي.
أنماط تبقي القوائم الكبيرة متجاوبة دون تعقيد الواجهة:
الطرق المحفوظة بطل هادئ. بدلًا من تعليم المستخدمين تكوين فلتر مثالي في كل مرة، أعطهم بعض الإعدادات المسبقة المطابقة لسيناريوهات حقيقية. فريق عمليات قد ينتقل بين "مدفوعات فاشلة اليوم" و"عملاء بقيمة عالية" بنقرة واحدة، مفهومة فورًا وأسهل للحفاظ على سرعة الخلفية.
إذا كنت تبني أداة داخلية في باني مدفوع بالمحادثة مثل Koder.ai، اعتبر الفلاتر جزءًا من تدفق المنتج، لا إضافة لاحقة. ابدأ من الأسئلة الأكثر شيوعًا، ثم صمم العرض الافتراضي والطرق المحفوظة حولها.
نادراً ما تحتاج شاشة القائمة نفس بيانات صفحة التفاصيل. إن كانت الـ API تعيد كل شيء عن كل شيء، فإنك تدفع ثمنًا مرتين: قاعدة البيانات تعمل أكثر، والمتصفح يستلم ويرسم أكثر مما يحتاج. تشكيل الاستعلام هو عادة طلب فقط ما تحتاجه القائمة الآن.
ابدأ بإعادة الأعمدة الضرورية فقط لعرض كل صف. لمعظم لوحات القيادة، هذا يكون id، بعض الوسوم، حالة، مالك، والطوابع الزمنية. النص الكبير، كائنات JSON، والحقول المحسوبة يمكن أن تنتظر حتى يفتح المستخدم الصف.
تجنّب الحِمَلات الثقيلة من الانضمامات للطلعة الأولى. الانضمامات مقبولة عندما تضرب الفهارس وتعيد نتائج صغيرة، لكنها تصبح مكلفة عندما تنضم لعدة جداول ثم تفرز أو تَفِلْتِر على البيانات المنضمة. نمط بسيط: جِب القائمة من جدول واحد بسرعة، ثم حمل التفاصيل المرتبطة عند الطلب (أو حمّل دفعات للصفوف المرئية فقط).
قَيِّد خيارات الفرز واجعلها على أعمدة مفهرسة. "الفرز بأي شيء" يبدو مفيدًا لكنه غالبًا يجبرك على فرز بطيء على مجموعات كبيرة. فضّل خيارات محدودة متوقعة مثل created_at، updated_at، أو status، وتأكد من فهرسة هذه الأعمدة.
كن حذرًا مع التجميعات على الخادم. COUNT(*) على مجموعة مصفّاة ضخمة، DISTINCT على عمود عريض، أو حساب صفحات إجمالية يمكن أن يهيمن على زمن الاستجابة.
نهج عملي:
COUNT وDISTINCT اختياريين، وخزنهم مؤقتًا أو قدم تقريبًا عند الإمكانإذا بنيت أدوات داخلية على Koder.ai، عرف استعلام قائمة خفيف منفصلًا عن استعلام التفاصيل في وضع التخطيط، حتى تبقى الواجهة سريعة مع نمو البيانات.
إن أردت شاشة قائمة تبقى سريعة عند 100k صف، يجب أن تقوم قاعدة البيانات بعمل أقل في كل طلب. معظم القوائم البطيئة ليست "بسبب كمية البيانات الكبيرة"، بل بسبب نمط وصول خاطئ للبيانات.
ابدأ بفهارس تتطابق مع ما يفعله المستخدمون فعليًا. إن كانت القائمة عادةً تُصفى بـ status وتُرتب بـ created_at، فستحتاج فهرسًا يدعم كلاهما بهذا الترتيب. وإلا قد تمسح قاعدة البيانات صفوفًا أكثر مما تتوقع ثم تفرزها، مما يصبح مكلفًا بسرعة.
إصلاحات تعطي عادةً أكبر مكاسب:
tenant_id, status, created_at).OFFSET العميقة. OFFSET يجبر قاعدة البيانات على المرور عبر صفوف كثيرة لتخطيها.مثال بسيط: جدول Orders داخلي يعرض اسم العميل، الحالة، المبلغ، والتاريخ. لا تنضم إلى كل الجداول المرتبطة وتسحب ملاحظات الطلب الكاملة لعرض القائمة. أعد فقط الأعمدة المستخدمة في الجدول، واحمل الباقي في طلب منفصل عند نقر المستخدم على الطلب.
إن كنت تبني بمنصة مثل Koder.ai، حافظ على هذه العقلية حتى لو تم توليد الواجهة من الدردشة. تأكد أن نقاط النهاية (endpoints) المولدة تدعم ترقيم المؤشر وحقول انتقائية، حتى يبقى عمل قاعدة البيانات متوقعًا مع نمو الجدول.
إن كانت شاشة القائمة بطيئة اليوم، لا تبدأ بإعادة كتابة كل شيء. ابدأ بتثبيت ما يبدو الاستخدام العادي، ثم حسّن المسار ذاك.
حدد العرض الافتراضي. اختر الفلاتر الافتراضية، ترتيب الفرز، والأعمدة الظاهرة. تصبح القوائم بطيئة عندما تحاول عرض كل شيء افتراضيًا.
اختر نمط الترقيم المناسب للاستخدام. إن كان المستخدمون يفحصون الصفحات الأولى غالبًا، الترقيم الكلاسيكي كافٍ. إن كانوا يقفزون بعُمق (صفحة 200+) أو تحتاج أداء مستقر بغض النظر عن العمق، استخدم ترقيم keyset (بناءً على ترتيب ثابت مثل created_at إضافةً إلى id).
أضف التفريغ لجسم الجدول. حتى لو كانت الخلفية سريعة، يمكن أن يخنق المتصفح عند رسم الكثير من الصفوف دفعة واحدة.
اجعل البحث والفلاتر سريعة. قم بتأخير الكتابة حتى لا تطلق طلبًا على كل ضغطة مفتاح. احتفظ بحالة الفلاتر في عنوان URL أو مخزن حالة مشترك حتى تعمل إعادة التحميل وزر العودة ومشاركة العرض بشكل موثوق. خزّن آخر نتيجة ناجحة حتى لا يومض الجدول فارغًا.
قِس ثم حسّن الاستعلامات والفهارس. سجّل زمن الخادم، زمن قاعدة البيانات، حجم الحمولة، وزمن العرض. ثم قِص الاستعلام: اختر فقط الأعمدة التي تظهر، طبّق الفلاتر مبكرًا، وأضف فهارس تطابق فلترك + فرز الافتراضي.
مثال: لوحة دعم داخلية بها 100k تذكرة. اجعل الافتراضي: Open، مخصص لفريقي، مرتب بالأحدث، عرض ستة أعمدة، وجلب فقط ticket id، الموضوع، الشخص المخصّص، الحالة، والطوابع الزمنية. مع ترقيم keyset وتفريغ، تحافظ على قابلية التوقع لكل من قاعدة البيانات والواجهة.
إن بنيت أدوات داخلية في Koder.ai، تتوافق هذه الخطة جيدًا مع دورة التكرار والفحص: عدّل العرض، اختبر التمرير والبحث، ثم اضبط الاستعلام حتى تبقى الصفحة سريعة.
أسرع طريقة لجعل شاشة قائمة تبدو معطلة هو معاملة 100k صف كصفحة بيانات عادية. معظم القوائم البطيئة تقع في فخاخ متوقعة.
أحدها الكبير هو رسم كل شيء وإخفاؤه بواسطة CSS. حتى إن بدا أن 50 صفًا فقط مرئية، المتصفح ما يزال يدفع ثمن إنشاء 100k عقدة DOM وقياسها وإعادة الرسم عند التمرير. إن كنت تحتاج قوائم طويلة، اركب فقط ما يراه المستخدم (تفريغ) وحافظ على مكونات الصف بسيطة.
التحرك في البحث يمكن أن يخرب الأداء خفية عندما يطلق كل ضغط مفتاح مسحًا كاملاً للجدول. يحدث ذلك عندما لا تدعم الفلاتر بفهارس، عندما تبحث عبر أعمدة كثيرة، أو عند تنفيذ استعلامات contains على حقول نص كبيرة بلا خطة. قاعدة جيدة: أول فلتر يصل إليه المستخدم يجب أن يكون رخيصًا في قاعدة البيانات، لا مجرد مريح في الواجهة.
مشكلة شائعة أخرى هي جلب السجلات الكاملة بينما تحتاج القائمة ملخصات فقط. صف القائمة عادة يحتاج 5 إلى 12 حقلًا، ليس الكائن الكامل، لا وصفًا طويلاً، ولا بيانات مرتبطة. سحب بيانات إضافية يزيد عمل قاعدة البيانات، وقت الشبكة، وتحليل الواجهة.
التصدير والإجماليات يمكن أن تجمد الواجهة إذا حسبتها على الخيط الرئيسي أو انتظرت طلبًا ثقيلًا قبل الاستجابة. اجعل الواجهة تفاعلية: ابدأ التصديرات في الخلفية، أظهر التقدم، وتجنّب إعادة حساب الإجماليات على كل تغيير فلتر.
أخيرًا، الكثير من خيارات الفرز قد ترتد عليك. إن سمحت بالفرز حسب أي عمود، ستنتهي إلى فرز مجموعات كبيرة في الذاكرة أو إجبار قاعدة البيانات على خطط بطيئة. احتفظ بالفرز لعدد صغير من الأعمدة المفهرسة، واجعل الفرز الافتراضي يطابق فهرسًا حقيقيًا.
فحص سريع:
عامل أداء القوائم كميزة منتج، لا تعديل لمرة واحدة. شاشة القائمة سريعة فقط عندما تبدو سريعة بينما أشخاص حقيقيون يمررون، يصفّون، ويُفرزون على بيانات حقيقية.
استخدم هذه القائمة لتتأكد أنك أصلحت الأشياء الصحيحة:
فحص واقعي بسيط: افتح القائمة، مرّر لمدة 10 ثوانٍ، ثم طبّق فلتر شائع (مثل الحالة: Open). إن تجمدت الواجهة، تكون المشكلة عادةً في العرض (كثير من صفوف DOM) أو معالجة ثقيلة على جهة العميل (فرز، تجميع، تنسيق) تحدث على كل تحديث.
خطوات تالية، بالترتيب، حتى لا تقفز بين الإصلاحات:
إن بنيت هذا مع Koder.ai (koder.ai)، ابدأ في وضع التخطيط: حدّد أعمدة القائمة، حقول الفلترة، وشكل استجابة الـ API أولًا. ثم كرر باستخدام لقطات واسترجاع التغييرات عندما تبطئ تجربة ما الشاشة.
ابدأ بتغيير الهدف من "تحميل كل شيء" إلى "إظهار أول صفوف مفيدة بسرعة". حسّن زمن الوصول لأول صف والتفاعل السلس عند التصفية والفرز والتمرير، حتى لو لم تُحمّل مجموعة البيانات كاملة دفعة واحدة.
قِس زمن الوصول لأول صف بعد التحميل أو تغيير الفلتر، زمن تحديث الفلتر/الفرز، حجم الحمولة (payload)، الاستعلامات البطيئة في قاعدة البيانات (خصوصًا COUNT(*) وعمليات SELECT العريضة)، ونوبات نشاط خيط المتصفح الرئيسي. هذه الأرقام ترتبط مباشرة بما يشعر به المستخدم من تأخير.
حدّد مؤقتًا أن واجهة البرمجة تعيد فقط 20 صفًا بنفس الفلاتر والترتيب. إن أصبحت الواجهة سريعة، فالعائق غالبًا في تكلفة الاستعلام أو حجم الحمولة؛ وإن بقيت بطيئة فالمشكلة عادة في العرض، التنسيق، أو الأعمال على كل صف في جهة العميل.
لا تعرض آلاف الصفوف في DOM دفعة واحدة، اجعل مكونات الصفوف بسيطة، وفضّل ارتفاع صف ثابت. كذلك تجنّب إجراء تنسيقات مكلفة للصفوف غير المرئية؛ احسبها واحتفظ بنتائجها مؤقتًا فقط عندما يصبح الصف مرئيًا أو عندما يفتحه المستخدم.
التفريغ (virtualization) يحافظ فقط على الصفوف المرئية (ومخزن صغير فوق وتحت) مركبة في DOM ويعيد استخدام عناصر DOM نفسها أثناء التمرير. مفيد عندما يقوم المستخدمون بالتمرير كثيرًا أو عندما تكون الصفوف "ثقيلة"—لكن يعمل بشكل أفضل إذا كان ارتفاع الصف ثابتًا وتخطيط الجدول متوقعًا.
الترقيم هو الإعداد الافضل لمعظم مهام الإدارة الداخلية لأنه يبقي المستخدمين متجهين ويحد من عمل الخادم. التمرير اللانهائي قد يناسب التصفح العرضي لكنه يخفي تكلفة الذاكرة والملاحة ما لم تضف إدارة واضحة للحالة والحدود.
الترقيم بالتحويل (offset) أبسط لكن يمكن أن يصبح أبطأ في الصفحات العميقة لأن قاعدة البيانات قد تحتاج لتخطي صفوف كثيرة. الترقيم بواسطة المؤشر (keyset/cursor) يبقى سريعًا عادة لأنه يستمر من العنصر الأخير المنظور، لكنه أقل ملاءمة للقفز إلى رقم صفحة محدد.
لا تجري استعلامًا عند كل ضغطة مفتاح. قم بتأخير (debounce) الإدخال، ألغِ الطلبات الجارية عند بدء طلب جديد، وابدأ بفلاتر تضييقية (مثل آخر 7 أيام أو "عناياتي") حتى يكون الاستعلام الأول صغيرًا ومفيدًا.
أعد فقط الحقول التي تعرضها القائمة فعليًا—عادةً مجموعة صغيرة مثل id، تسمية، الحالة، المالك، والطوابع الزمنية. أزِل النصوص الكبيرة وحقول JSON والبيانات المرتبطة إلى استعلام تفاصيل تُشغل عند فتح الصف.
اجعل الفلتر والفرز الافتراضيين يعكسان الاستخدام الحقيقي ثم أضف فهارس تدعم هذا النمط، غالبًا فهرس مركب يجمع بين حقول المستأجر/الفلتر وعمود الفرز. اعتبر الأرقام الإجمالية (COUNT) اختيارية: احسبها لاحقًا، خزّنها مؤقتًا، أو قدّم تقريبًا إذا لم تكن الحاجة للأرقام الدقيقة ضرورية.