المستوى: متوسط — يفترض إنك بتشتغل React بشكل يومي وعارف useState و useEffect وفاهم إزاي JSX بيتحول لـ DOM.
React Virtualization: ارسم قائمة 10,000 صف بدون ما الواجهة تتجمّد
لو جدول React عندك بـ 10,000 صف بياخد 4 ثواني لأول رسم وكل scroll بيعلّق نص ثانية، المشكلة مش في React نفسه. المشكلة إنك بترسم 60,000 عقدة DOM دفعة واحدة، والمتصفح مش قادر يحرّكهم بسرعة. List Virtualization بيخلّي الـ DOM يحتوي 30 صف فقط في أي لحظة، وبيرسم الباقي ساعة ما يدخل في نطاق العين. النتيجة العملية: وقت أول رسم بينزل من 4,180ms لـ 92ms، واستجابة الـ scroll من 380ms لـ 4ms، على نفس البيانات بالظبط.
المشكلة باختصار
كل عنصر JSX بيتحول لعقدة DOM حقيقية في المتصفح. لو جدولك فيه 10,000 صف وكل صف فيه 6 خلايا، أنت بتطلب من المتصفح يدير 60,000 عقدة. الذاكرة بتطلع، الـ layout pass بيتأخر، وكل ما المستخدم يعمل scroll المتصفح يعيد حساب positions لكل العقد دي. النتيجة: واجهة تتجمّد لمدة كافية تخلّي المستخدم يحس إن التطبيق "بيهنج"، حتى لو React نفسه مش بيرسم تاني.
مثال يقرّب الفكرة قبل التعريف العلمي
تخيّل سينما فيها 10,000 كرسي. لو الإدارة قررت تطبع تذكرة لكل كرسي مع بداية كل عرض، حتى الكراسي الفاضية واللي مش هيقعد فيها حد، ده هدر مهول من الورق والوقت. الحل العقلاني: اطبع تذاكر للصفوف اللي قدام شبّاك التذاكر فقط (30 كرسي مثلاً)، ولما الناس تتقدّم في الصف اطبع اللي ظهر قدامك. ده بالظبط اللي بيعمله Virtualization مع الـ DOM. السينما = الـ scroll container، الكراسي = الـ rows، شبّاك التذاكر = الـ viewport.
التعريف العلمي
List Virtualization (والمعروف كمان بـ Windowing) هو نمط رسم بيخلّي عدد العناصر الموجودة في DOM ثابت تقريبًا بصرف النظر عن حجم البيانات الكلي. الخوارزمية بتعمل التالي على كل scroll event:
- تقرأ
scrollTopمن الـ container. - تحسب الـ range من الـ items اللي المفروض تظهر بناءً على ارتفاع كل صف.
- ترسم العناصر دي فقط، وتضيف
overscanصغير فوق وتحت كاحتياط. - تحجز ارتفاع كلي وهمي يساوي مجموع ارتفاعات كل الصفوف، عشان الـ scrollbar يفضل بنفس الطول الصحيح.
كود شغّال بـ react-window
المكتبة الأشهر دلوقتي هي react-window من Brian Vaughn (نفس مؤلف react-virtualized لكن أخف بمقدار 7x في حجم الـ bundle). الكود ده شغّال زي ما هو:
npm install react-window