مكوّنات الخادم بعد سنة من الاستعمال
ما يكلّفه النموذج الذهني، وأين يؤتي ثماره
تُشرح مكوّنات الخادم في كل مكان بوصفها مكسباً في حجم الحزمة، وهذا صحيح، وليس هو الجزء الذي غيّر طريقتي في كتابة React. الجزء الذي غيّر طريقتي هو أن الافتراضي انقلب. المكوّنات صارت على الخادم حتى أقول غير ذلك، وهذا الانقلاب الواحد أعاد ترتيب شيفرتي أكثر من أي واجهة برمجية في إطار العمل.
01الافتراضي انقلب
في النموذج القديم كان كل مكوّن مكوّن عميل، وكان الخادم مكاناً تجلب منه. أما الآن فالخادم هو حيث تعيش المكوّنات، وتوجيه العميل صار استثناءً عليّ أن أبرّره. يبدو هذا فارقاً بسيطاً في الصياغة وهو ليس كذلك. إنه يغيّر ما يُسمح للمكوّن أن يكونه. مكوّن الخادم يستطيع انتظار البيانات مباشرة في جسده. ويستطيع القراءة من نظام الملفات، وحمل سرّ، واستدعاء خدمة داخلية، لأن شيئاً من ذلك لا يُشحن. وما لا يستطيعه هو تذكّر أي شيء بين عمليتي تصيير أو الاستجابة لنقرة. لذلك تحوّل السؤال الذي أطرحه أثناء البناء من أين أجلب هذا إلى إلى أي عمق أستطيع دفع التفاعلية في الشجرة. والجواب عادةً أعمق مما توحي غريزتي. صفحة بدت وكأنها تحتاج أن تكون تفاعلية تتبيّن غالباً شجرة ثابتة بورقة تفاعلية واحدة، وحالما تجد تلك الورقة تحصل بقية الصفحة على حق البقاء على الخادم. هذا هو المكسب الفعلي. أما تحسّن حجم الحزمة فنتيجة لا هدف.
02أين توضع الحدود
الخطأ الذي كررته في البداية كان وضع توجيه العميل عالياً أكثر من اللازم. قسم يحتاج مفتاح تبديل، فيصبح القسم مكوّن عميل، فتصبح كل بطاقة داخله مكوّن عميل، فتعبر معه تنسيقات البيانات ومجموعة الأيقونات ومنطق التواريخ إلى الحزمة. التوجيه ليس خاصية مكوّن، بل خاصية شجرة فرعية. وما ينجح أفضل هو معاملة التفاعلية بوصفها غلافاً. الغلاف التفاعلي مكوّن عميل يستقبل أبناءً، والأبناء مكوّنات خادم تُمرَّر عبره. الحالة تعيش في الغلاف، والمحتوى يبقى على الخادم، وتقع الحدود تماماً حيث يبدأ السلوك لا حيث تبدأ الميزة. في هذا الموقع تفعل قائمة المقالات ذلك: مفتاح التبديل بين الشبكة والقائمة وحقل البحث المؤجَّل غلاف عميل، وكل بطاقة تُصيَّر داخله مكوّن خادم لا يدخل الحزمة أبداً. استغرقني هذا النمط وقتاً لأستوعبه لأنه يبدو مقلوباً. أنت تمرّر ناتجاً مُصيَّراً إلى مكوّن تفاعلي بدل أن تستورده داخله.
03جلب البيانات صار مملاً
هذا هو الجزء الذي لم أتوقع أن أستمتع به بهذا القدر. الجلب في مكوّن خادم هو انتظار في جسد المكوّن. لا تأثير جانبي، ولا مصفوفة اعتماديات، ولا حالة تحميل، ولا تنظيف عند إزالة المكوّن، ولا سباق بين طلبين قيد التنفيذ يحلّ فيه الأبطأ أخيراً فيدهس البيانات الأحدث. هذا الأخير خطأ كتبته أكثر من مرة ولن أكتبه ثانية في هذا النموذج. وما يحلّ محلّه انضباط مختلف. لأن كل انتظار في الشجرة نقطة يمكن أن يتوقف عندها التصيير، تتحوّل الانتظارات المتسلسلة في مكوّنات متداخلة إلى شلال لا يلاحظه أحد حتى تصبح الصفحة بطيئة الإحساس. والعلاج هو نفسه دائماً: ابدأ الطلبات معاً وانتظرها معاً بدل واحداً تلو الآخر. ولأن إطار العمل يخزّن الطلبات ويزيل تكرارها ضمن دورة التصيير الواحدة، فإن طلب البيانات نفسها في ثلاثة مكوّنات مقبول تماماً، وهذا يزيل الضغط المعتاد لرفع كل شيء إلى جلب واحد في الأعلى وتمريره نزولاً عبر الخصائص.
04الحواف الحادة
رسائل الخطأ عند الحدود لا تزال أخشن ما في الأمر. تمرير دالة إلى مكوّن عميل يفشل أثناء التشغيل برسالة تصف مشكلة التسلسل بدل أن تشير إلى الخاصية التي مرّرتها، والعثور عليها يعني قراءة الشجرة بنفسك. القاعدة بسيطة بما يكفي حالما تعرفها، وهي أن كل ما يعبر الحدود يجب أن يكون قابلاً للتسلسل، لكن الأدوات لا تساعدك في العثور على المخالفة. والسياق هو التكيّف الآخر. مكوّن الخادم لا يستطيع استهلاكه، لذا فإن أي شيء عام فعلاً، كسمة أو قاموس، يجب أن يوفّره مكوّن عميل عالٍ في الشجرة ويُقرأ من جهة العميل فقط. في هذا الموقع تُمرَّر الترجمات إلى مكوّنات الخادم كوسائط عادية، وإلى مكوّنات العميل عبر مزوّد، ما يعني أن البيانات نفسها تصل بمسارين مختلفين. إنه يعمل، وليس أنيقاً. وآخرها عادة لا علة. من السهل أن تنسى أن مكوّن الخادم يُعاد تنفيذه مع كل طلب، فتضع فيه شيئاً مكلفاً كان سيُحفَظ في الذاكرة على العميل سابقاً.
الخلاصة
مكوّنات الخادم ليست ميزة تتبنّاها بقدر ما هي افتراضٌ تعتاده. ادفع حدود العميل إلى أعمق نقطة تحتملها الشجرة، ومرّر أبناءً مُصيَّرين على الخادم إلى أغلفة تفاعلية بدل استيرادهم داخلها، وتعامل مع التسلسل كقيد حقيقي لا كتفصيل تقني. والعائد ليس أساساً الحزمة الأصغر، بل أن معظم الشيفرة تتوقف عن التفكير في العميل أصلاً.