Skip to content

التمرير الافتراضي

لماذا يجري داخل المحرّك

يأتي تأخّر الذيل في القوائم الافتراضية المبنية على DOM من هذه السلسلة: يعود حدث التمرير إلى الخيط الرئيسي، فيستدعي setState، ثمّ المقارنة، ثمّ إعادة التخطيط. وما إن ينشغل الخيط الرئيسي حتى تسقط الإطارات.

يضع doper حساب النافذة داخل النواة: التمرير المستقرّ لا يستدعي الغلاف إطلاقًا. ولا يفعل الغلاف سوى تجسيد المجال المرئي وفق نافذة التسخين التي خطّطت لها النواة؛ وإن لم تكن البيانات جاهزة رُسم عنصر نائب واستُكمل في إطارات لاحقة.

الاستعمال

ts
createElement("virtualList", {
  width: 480,
  height: 640,
  itemCount: 1_000_000,
  estimatedItemHeight: 32,
  renderItem: (index: number) =>
    createElement("container", {
      width: 480,
      height: 32,
      children: createElement("text", { value: `الصف ${index}` }),
    }),
});

estimatedItemHeight مجرّد تقدير أوّلي. وبعد قياس الارتفاع الحقيقي تصحّح النواة موضع المرساة عبر شجرة المجاميع البادئة (Fenwick)، فلا يقفز موضع التمرير.

المعاملات القابلة للضبط

الخاصيّةالأثر
baseOverscanViewportsمدى التسخين المتماثل (بمضاعفات نافذة العرض)
velocityHorizonSecondsأفق إسقاط السرعة المستخدم في توقّع الاتجاه
maximumAheadViewportsحدّ التسخين في اتّجاه واحد
scrollX / scrollYموضع تمرير برمجي (يُصدر ScrollTo عند التغيّر فقط)

يسخّن توقّع الاتجاه جهة الحركة أوّلًا عند الدفع السريع، بدل تبديد الميزانية على الجهتين بالتساوي.

التمرير البرمجي

ts
// تغيير الخاصيّة يُصدر تعديل ScrollTo واحدًا
root.render(createElement("virtualList", { scrollY: 500_000 * 32 /* ... */ }));

أو عبر واجهة التحكّم المباشر على الجذر، وهي مخصّصة للإيماءات المخصّصة:

ts
root.beginScroll(handle);
root.scrollBy(handle, 0, deltaY, elapsedMs);
root.endScroll(handle); // تتكفّل النواة بتقدير سرعة الاندفاع

ويأتي handle من ردّ نداء ref الخاصّ بالعنصر (NodeHandle).

عجلة الفأرة ولوحة اللمس

تطابق مسافة التمرير بالعجلة ما يفعله المتصفّح، لكنّ منحنى النقل ينقسم بحسب مصدر الإدخال: تُطبَّق الفروق عالية الدقّة (لوحة اللمس) بنسبة ١:١ فورًا ويبقى القصور الذاتي من تدفّق أحداث نظام التشغيل، بينما تتراكم نقرات العجلة المنفصلة نحو هدف متحرّك يُقارَب بتباطؤ أُسّي، مقيَّدًا بحدود المحتوى بلا تجاوز، تمامًا كما في المتصفّح.

التداخل والتحرير

حين يبدأ سحب المؤشّر فوق نصّ قابل للتحرير يسبق تحديدُ النصّ سحبَ التمرير، وتظلّ العجلة تمرّر أقرب سلف قابل للتمرير. وتتحدّد هذه الأولوية بعمق مسار الإصابة ولا تحتاج إلى تدخّل من التطبيق.

معيار الأداء

يشكّل قياس الأداء الآلي على تجهيزة ثابتة (مليون صفّ، عشرون ألف إطار) جزءًا من بوّابة الدمج. وحاليًا يقلّ P95/P99 لإعادة التشغيل عن الميكروثانية، ولا يظهر نموّ ذاكرة خارج السيطرة بعد ثلاثين دقيقة من التمرير المتواصل.

أمّا P95/P99 على الأجهزة الحقيقية وزمن استجابة الإدخال فيندرجان تحت تأهيل المنصّة وليسا شرطًا لإنهاء العمل الهندسي. وهذا الفصل مقصود: فهو يمنع تعطيل العمل ببيانات أجهزة غير قابلة للاستنساخ، ويمنع كذلك تقديم أرقام هندسية على أنّها وعد بخصوص الأجهزة.

يمكنك رؤية مؤشّرات الإطارات لحظيًا في عرض التمرير داخل Playground.

منشور برخصة MIT