مقدمة لرد فعل الألياف المعمارية

مرحبا يا هبر! أوجه انتباهكم إلى ترجمة لمقال "React Fiber Architecture" من إعداد أندرو كلارك .


دخول


React Fiber هو تطبيق تدريجي لخوارزمية React الرئيسية. هذا هو تتويج لدراسة لمدة عامين من قبل فريق تطوير React.


هدف Fiber هو زيادة الإنتاجية عند تطوير مهام مثل الرسوم المتحركة وتنظيم العناصر على الصفحة ونقل العناصر. الميزة الرئيسية هي التقديم التدريجي: القدرة على تقسيم عمل التقديم إلى وحدات وتوزيعها بين إطارات متعددة.


تشمل الميزات الرئيسية الأخرى القدرة على إيقاف أو إلغاء أو إعادة استخدام التحديثات الواردة لشجرة DOM ، والقدرة على إعطاء الأولوية لأنواع مختلفة من التحديثات ، وكذلك تنسيق الأوليات.


قبل قراءة هذا المقال ، نوصيك بأن تتعرف على المبادئ الأساسية لرد الفعل:



نظرة عامة


ما هي المصالحة؟


المصالحة عبارة عن خوارزمية React المستخدمة لتمييز شجرة عنصر واحد عن آخر لتحديد الأجزاء التي ستحتاج إلى استبدال.


التحديث هو تغيير في البيانات المستخدمة لتقديم تطبيق React. هذا عادة ما يكون نتيجة استدعاء الأسلوب setState؛ النتيجة النهائية لتقديم المكون.


تتمثل الفكرة الرئيسية في React API في التفكير في التحديثات كما لو أنها قد تؤدي إلى عرض كامل للتطبيق. يتيح هذا للمطور التصرف بشكل تعريفي ، ولا تقلق بشأن مدى عقلانية انتقال التطبيق من حالة إلى أخرى (من A إلى B ، B إلى C ، C إلى A ، إلخ).


بشكل عام ، لا يؤدي تقديم التطبيق بالكامل لكل تغيير إلا إلى التطبيقات الأكثر تقليدية. في العالم الحقيقي ، يؤثر هذا سلبًا على الأداء. يشتمل الفعل على تحسينات تنشئ طريقة عرض كاملة دون التأثير على حصة كبيرة من الأداء. تتضمن معظم هذه التحسينات عملية تسمى المصالحة.


المصالحة عبارة عن خوارزمية وراء ما اعتدنا أن نطلق عليه "DOM الظاهري". يبدو هذا التعريف كالتالي: عند تقديم تطبيق React ، يتم إنشاء شجرة العناصر التي تصف التطبيق في الذاكرة المحجوزة. ثم يتم تضمين هذه الشجرة في بيئة العرض - باستخدام مثال تطبيق المستعرض ، يتم ترجمته إلى مجموعة من عمليات DOM. عند تحديث حالة التطبيق (عادةً عن طريق استدعاء setState) ، يتم إنشاء شجرة جديدة. تتم مقارنة الشجرة الجديدة بالشجرة السابقة لحساب وتمكين بالضبط تلك العمليات اللازمة لإعادة رسم التطبيق المحدث.


على الرغم من أن Fiber عبارة عن تطبيق وثيق للموفق ، إلا أن الخوارزمية عالية المستوى الموضحة في وثائق React ستكون متطابقة إلى حد كبير.


المفاهيم الأساسية:


  • تشير الأنواع المختلفة من المكونات إلى توليد أشجار مختلفة تمامًا. React لن تحاول مقارنتها ، ولكن ببساطة استبدل الشجرة القديمة تمامًا.
  • يتم تمييز القوائم باستخدام المفاتيح. يجب أن تكون المفاتيح "ثابتة ويمكن التنبؤ بها وفريدة من نوعها".

المصالحة مقابل التقديم


تعد شجرة DOM واحدة من البيئات التي يمكن لـ React أن ترسمها ، والباقي يمكن أن يعزى إلى iOS الأصلي وطرق عرض Android باستخدام React Native (وهذا هو السبب في أن Virtual Dom هو اسم غير مناسب قليلاً).


السبب في أن React يدعم الكثير من الأهداف هو أن React بني بحيث تكون المصالحة وتقديمها من مراحل منفصلة. يقوم الموفق ، الذي يعمل ، بحساب أجزاء الشجرة التي تم تغييرها ، ويستخدم العارض لاحقًا هذه المعلومات لتحديث الشجرة المقدمة مسبقًا.


يعني هذا الفصل أن React DOM و React Native يمكنهم استخدام آليات التقديم الخاصة بهم عند استخدام نفس أداة التخزين المؤقت الموجودة في React Core.


Fibre هو تطبيق معاد تصميمه لخوارزمية التسوية. له علاقة غير مباشرة بالتقديم ، في حين يمكن تغيير آليات التقديم (تقديم) لدعم جميع مزايا البنية الجديدة.


التخطيط عملية تحدد متى يجب إكمال العمل.


العمل - أي الحسابات التي يجب القيام بها. العمل عادة ما يكون نتيجة تحديث (على سبيل المثال ، استدعاء setState).


مبادئ هندسة React جيدة جدًا بحيث لا يمكن وصفها إلا بهذا الاقتباس:


في تطبيق React الحالي ، فإنه يعبر الشجرة بشكل متكرر ويدعو وظائف التقديم على الشجرة المحدثة بالكامل في علامة واحدة (16 مللي ثانية). ومع ذلك ، في المستقبل ، سيكون قادرًا على إلغاء بعض التحديثات لمنع القفزات الإطار.
هذا موضوع تمت مناقشته بشكل متكرر بخصوص تصميم React. تقوم بعض المكتبات الشائعة بتنفيذ نهج "الدفع" ، حيث يتم إجراء العمليات الحسابية عند توفر بيانات جديدة. ومع ذلك ، تلتزم React بنهج السحب ، حيث يمكن إلغاء الحسابات عند الضرورة.
React ليست مكتبة لمعالجة البيانات المعممة. هذه مكتبة لبناء واجهات المستخدم. نعتقد أنه يجب أن يكون له موقع فريد في التطبيق من أجل تحديد الحسابات المناسبة وأيها ليست في الوقت الحالي.
إذا كان هناك أي شيء وراء الكواليس ، فيمكننا التراجع عن كل المنطق المرتبط به. إذا وصلت البيانات بشكل أسرع من معدل عرض الإطار ، فيمكننا دمج التحديثات. يمكننا زيادة أولوية العمل الذي يأتي كنتيجة لتفاعل المستخدم (مثل ظهور رسم متحرك عند الضغط على زر) في مقابل العمل الأقل أهمية في الخلفية (تقديم محتوى جديد محمل من الخادم) لمنع تنزيل الإطارات.

المفاهيم الأساسية:


  • في واجهات المستخدم ، ليس من المهم أن يتم تطبيق كل تحديث على الفور ؛ في الواقع ، سيكون هذا السلوك لا لزوم له ، وسوف يسهم في سقوط الأطر وتدهور UX.
  • لأنواع مختلفة من التحديثات لها أولويات مختلفة - يجب أن تنتهي تحديثات الرسوم المتحركة بشكل أسرع من تحديث تخزين البيانات على سبيل المثال.
  • يتطلب النهج القائم على الدفع من التطبيق (أنت ، المطور) أن يقرر كيفية تخطيط العمل. يسمح النهج القائم على السحب للإطار باتخاذ القرارات نيابة عنك.

رد الفعل في الوقت الحالي ليس لديه ميزة التخطيط إلى حد كبير ؛ سيتم رسم نتائج التحديث للشجرة بأكملها على الفور. إن اختيار العناصر الموجودة في خوارزمية React kernel لتطبيق الجدولة هو الفكرة الأساسية لـ Fiber.


ما هو الألياف؟


سنناقش قلب بنية React Fiber. الألياف عبارة عن تجريد على مستوى أقل من التطبيق أكثر من اعتاد المطورين على التفكير. إذا كنت تفكر في محاولاتك لفهمها ميؤوس منها ، فلا تشعر بالإحباط (لست وحدك). استمر في البحث وسوف تؤتي ثمارها في النهاية.


و كذلك!


لقد حققنا هذا الهدف الأساسي من بنية الألياف - السماح React بالاستفادة من التخطيط. على وجه التحديد ، نحتاج إلى أن نكون قادرين على:


  • التوقف عن العمل والعودة إليها في وقت لاحق.
  • إعطاء الأولوية لأنواع مختلفة من العمل.
  • إعادة استخدام العمل المنجز في وقت سابق.
  • قم بإلغاء العمل إذا لم تعد هناك حاجة إليه.

للقيام بكل هذا ، نحتاج أولاً إلى تقسيم العمل إلى وحدات. بمعنى ما ، هذا هو الألياف. يمثل الألياف وحدة من العمل.


للمضي قدماً ، دعنا نعود إلى المفهوم الأساسي لـ "مكونات React كبيانات وظيفة" ، والتي يتم التعبير عنها غالبًا على النحو التالي:


v = f(d) 

باستخدام هذا ، يكون تقديم تطبيق React مثل استدعاء دالة يحتوي جسمها على مكالمات إلى وظائف أخرى ، وهكذا. هذا التشبيه مفيد عند التفكير في الألياف.


وتسمى الطريقة التي تتحقق فيها أجهزة الكمبيوتر بشكل أساسي من ترتيب تنفيذ برنامج مكدس الاستدعاءات. عند اكتمال الوظيفة ، تتم إضافة حاوية المكدس الجديدة إلى المكدس. تمثل حاوية المكدس هذه العمل المنجز بواسطة دالة.


عند العمل مع واجهات المستخدم ، يتم القيام بالكثير من العمل فورًا وهذه مشكلة ، يمكن أن تؤدي إلى قفزات في الرسوم المتحركة وستظهر بشكل متقطع. علاوة على ذلك ، قد لا يكون بعض هذا العمل ضروريًا إذا تم استبداله بالتحديث الأحدث. في هذه المرحلة ، تتباين المقارنة بين واجهة المستخدم والوظيفة ، لأن المكونات لها مسؤولية محددة أكثر من الوظائف بشكل عام.
تطبق أحدث المستعرضات و React Native واجهات برمجة التطبيقات التي تساعد في حل هذه المشكلة:
requestIdleCallback يوزع المهام بحيث يتم استدعاء الوظائف ذات الأولوية المنخفضة في فترة بسيطة ، ويوزع requestAnimationFrame المهام بحيث يتم استدعاء الوظائف ذات الأولوية العالية في الإطار التالي. المشكلة هي أنه لاستخدام واجهات برمجة التطبيقات هذه ، تحتاج إلى تقسيم عمل العرض إلى وحدات تدريجية. إذا كنت تعتمد فقط على مكدس الاستدعاءات ، فسيستمر العمل حتى تكدس المكدس.


ألن يكون الأمر رائعًا إذا أمكننا تخصيص سلوك مكدس الاتصال لتحسين عرض أجزاء واجهة المستخدم؟ هل سيكون من الرائع أن نتمكن من كسر مكدس الاتصال لمعالجة الحاويات يدويًا؟


هذا هو استدعاء الألياف التفاعلية. Fibre هو تطبيق مكدس جديد مصمم لمكونات React. يمكنك التفكير في ألياف واحدة كحاوية مكدس افتراضية.


تتمثل ميزة هذا التطبيق للمكدس في أنه يمكنك حفظ مكدس الحاويات في الذاكرة وتنفيذها ثم (وأين) التي تريدها. هذا هو تعريف حاسم لتحقيق أهداف التخطيط الخاصة بك.


بالإضافة إلى التخطيط ، تكشف الإجراءات اليدوية مع المكدس عن إمكانات مفاهيم مثل التناسق (التزامن) ومعالجة الأخطاء (حدود الخطأ).


في القسم التالي ، ننظر إلى بنية الألياف.


هيكل الألياف


على وجه التحديد ، "الليف" هو كائن JavaScript يحتوي على معلومات حول مكون وإدخاله وإخراجه.


الألياف تتسق مع الحاوية المكدسة ، لكنها تتسق أيضًا مع جوهر المكون.


فيما يلي بعض الخصائص المهمة لـ "الألياف" (هذه القائمة ليست شاملة):


اكتب والمفتاح


اكتب والمفتاح تخدم الألياف وكذلك عناصر رد الفعل. في الواقع ، عندما يتم إنشاء الألياف ، يتم نسخ هذين الحقلين إليه مباشرة.


يصف نوع الألياف المكون الذي يتوافق معه. لتكوين المكونات ، الكتابة هي وظيفة أو فئة مكون. بالنسبة لمكونات الخدمة (div ، span) ، النوع عبارة عن سلسلة.


من الناحية النظرية ، النوع عبارة عن وظيفة يتم تتبع تنفيذها من خلال حاوية مكدس.


جنبا إلى جنب مع النوع ، يتم استخدام المفتاح عند مقارنة الأشجار لتحديد ما إذا كان يمكن إعادة استخدام الألياف.


الطفل والاخوة

تشير هذه الحقول إلى ألياف أخرى ، تصف البنية العودية للألياف.


يتوافق الطفل التابع مع القيمة التي تم إرجاعها نتيجة استدعاء طريقة التجسيد على المكون. في المثال أدناه:


 function Parent() { return <Child /> } 

الطفل الأم الوالد يتوافق مع الطفل.


يتم استخدام الحقل النسبي (أو الجار) إذا قام التجسيد بإرجاع العديد من الأطفال (ميزة جديدة في الألياف):


 function Parent() { return [<Child1 />, <Child2 />] } 

ألياف الأطفال هي قائمة مرتبطة منفردة على رأسها الطفل الأول. في هذا المثال ، يكون الوالد هو الطفل 1 ، وأقارب الطفل الأول هم الطفل الثاني.


بالعودة إلى قياسنا بالوظائف ، يمكنك التفكير في الألياف الفرعية كدالة تسمى في النهاية (دالة تسمى الذيل).


مثال ويكيبيديا:


 function foo(data) { a(data); return b(data); } 

في هذا المثال ، تكون الدالة التي تسمى الذيل هي b.


قيمة الإرجاع (العودة)


عودة الألياف هي الألياف التي يجب أن يعود إليها البرنامج بعد معالجة الألياف الحالية. هذا هو نفس إرجاع عنوان الحاوية المكدس.
ويمكن أيضا أن تعتبر الألياف الأم.


إذا كانت الألياف تحتوي على ألياف أطفال متعددة ، فإن إرجاع كل ألياف أطفال تُرجع الألياف الأم. في المثال أعلاه ، تعتبر الألياف المرتجعة من Child1 و Child2 هي Parent.


الخصائص الحالية وذاكرة التخزين المؤقت (pendingProps و memorisedProps)


من الناحية النظرية ، والخصائص هي وسيطات وظيفة. خصائص الألياف الحالية هي مجموعة من هذه الخصائص في بداية التنفيذ ، أما الخصائص المخزنة مؤقتًا فهي مجموعة في نهاية التنفيذ.


عندما يتم تخزين خصائص انتظار الإدخال ، فهذا يعني أنه يمكن إعادة استخدام مخرجات الألياف السابقة بدون أي حسابات.


أولوية العمل الحالي (في انتظار العمل)


يتم عرض مقدار الأولوية في تحديد العمل بواسطة الألياف. تتضمن وحدة مستوى الأولوية في React ReactPrioritylevel مستويات مختلفة من الأولوية وما تمثله.


بدايةً من نوع NoWork ، وهو 0 ، يحدد الرقم الأعلى الأولوية الأقل. على سبيل المثال ، يمكنك استخدام الوظيفة التالية للتحقق مما إذا كانت أولوية الألياف أكبر من المستوى المحدد:


 function matchesPriority(fiber, priority) { return fiber.pendingWorkPriority !== 0 && fiber.pendingWorkPriority <= priority } 

هذه الوظيفة هي لأغراض التوضيح فقط ؛ أنها ليست جزءًا من قاعدة بيانات React Fiber.


يستخدم المجدول حقل الأولوية للعثور على وحدة العمل التالية التي يمكن تنفيذها. سنناقش هذه الخوارزمية في القسم التالي.


بديل (أو زوج)


تحديث الألياف (التدفق) - وهذا يعني عرض إخراجها على الشاشة.


الألياف قيد التطوير (العمل قيد التنفيذ) - الألياف التي لم يتم بناؤها بعد ؛ بمعنى آخر ، إنها حاوية مكدس لم يتم إرجاعها بعد.


في أي وقت ، لا يحتوي جوهر المكون على أكثر من حالتين للألياف التي تتوافق مع: الألياف في الحالة الحالية ، أو الألياف المحدثة أو الألياف قيد التطوير.


يتبع الألياف الحالية الألياف التي يتم تطويرها ، وبعد ذلك يتم تحديث الألياف.


يتم إنشاء حالة الألياف التالية بتكاسل باستخدام وظيفة cloneFiber. دائمًا عند إنشاء كائن جديد ، سيحاول cloneFiber إعادة استخدام بديل (زوج) من الألياف إذا كان موجودًا ، مع تقليل تكلفة الموارد.


يجب أن تفكر في مجال البخار (أو البديل) كتفاصيل للتنفيذ ، لكنه ينبثق كثيرًا في الوثائق بحيث كان من المستحيل ببساطة عدم ذكره.


الاستنتاج هو عنصر خدمة (أو مجموعة من عناصر الخدمة) ؛ العقد ورقة تتفاعل التطبيقات. إنها خاصة بكل بيئة عرض (على سبيل المثال ، في المتصفح ، يكون "div" ، "span" ، إلخ). في JSX ، يتم الإشارة إليها كأسماء علامات صغيرة.


خلاصة القول: أوصي بتجربة ميزات بنية React v16.0 الجديدة

Source: https://habr.com/ru/post/ar444276/


All Articles