تخطّى إلى المحتوى الرئيسي
Signals مقابل React Compiler: مواجهة التفاعلية الدقيقة الحبيبية

Signals مقابل React Compiler: مواجهة التفاعلية الدقيقة الحبيبية

May 20, 2026
هندسة الواجهة الأمامية
5 دقيقة قراءة

عن الكاتب

Ahmed Mahmoud

Ahmed Mahmoud

كاتب ومطوّر

مهندس برمجيات شغوف بتطوير الويب وتصميم تجربة المستخدم.

مؤسّس ديفيا · eng-ahmed.com ↗

لأكثر من عقد، يطارد مجتمع الواجهة الأمامية الهدف الجوهري نفسه: تقليل العمل غير الضروري. إعادة رَنْدَرة شجرة مكونات كاملة عندما تتغيّر قيمة واحدة فقط كانت ضريبة الأداء العامة لأطر واجهات المستخدم التصريحية، وتطوّرت الحلول عبر عدة أجيال — memoization وdiff لـ virtual DOM وإدارة المفاتيح الدقيقة وتقسيمات السياق اليدوية. في 2026، وصلت إجابتان متمايزتان إلى نضج الإنتاج في الوقت نفسه، وتتخذان مقاربتين فلسفيتين متعاكستين.

على جانب واحد تجلس أُطر signals. تقاربت SolidJS وVue 4 وAngular 20 وSvelte 5 جميعها على قيم قابلة للملاحظة — تُعرف بـ signals — كبدائي تفاعلي رئيسي. يشترك المكون عبر قراءة الـ signal؛ وعندما يتغيّر الـ signal، فقط عقد DOM المحددة المعتمدة عليه تُعاد تنفيذها. لا يوجد diff لـ virtual DOM للأجزاء غير المتغيّرة لأنه لا يوجد virtual DOM للـ diff. يتتبع وقت التشغيل رسم التبعيات على مستوى القيمة، وتتدفق التحديثات عبره كالماء يجد أقصر طريق.

على الجانب الآخر تجلس React، التي اتخذت رهانًا مختلفًا جوهريًا: بدل تغيير وقت التشغيل، غيّر ما يكتبه المطور. يحلل React Compiler مصدر مكوّنك في وقت البناء، ويحدّد القيم والحسابات المستقرة، ويُدرج memoization تلقائيًا حيث يفيد. من منظور المطور، تحذف كل useMemo وuseCallback كتبتها — يتعامل المُجمِّع معها نيابة عنك، وبصورة أكثر صحة مما فعلته يدويًا.

المشكلة التي تحلها كلا المقاربتين هي نفسها: النموذج الذهني الكلاسيكي لـ React يعيد رَنْدَرة شجرات مكونات كاملة عند تغيّر الحالة، ثم يعتمد على المطور لتذكّر React.memo وuseMemo وuseCallback لتجنب الهدر. معظم الفرق تخطئ في هذا بطرق دقيقة، وضريبة التفاعلية الناتجة هي بالضبط سبب أن مقياس INP من Core Web Vitals — الذي أدخلته Google خصيصًا لقياس التفاعل المتجاوب عبر عمر الصفحة — هو المقياس الذي تفشل فيه معظم الفرق.

دعني أمشي عبر نموذج signals بمثال SolidJS ملموس: 'const [count, setCount] = createSignal(0);' متبوعًا بـ '<button onClick={() => setCount(c => c + 1)}>{count()}</button>'. فقط عقدة النص التي تحتوي على قيمة العدّ تُعاد رَنْدَرتها عند نقر الزر. عنصر الزر ومعالج حدثه وكل قطعة أخرى من DOM المحيط تبقى دون مساس. يتتبع وقت التشغيل القراءة في تعبير JSX ويعيد بناء رسم التبعيات تلقائيًا. أوقات تشغيل أصغر، وعدم تطابق هيدراشن أقل، ونموذج تأليف حيث 'ما الذي يُعاد رَنْدَرته' شيء يمكن قراءته من الصفحة بدلًا من التخمين.

تشعر مقاربة React Compiler مختلفة في الاستخدام. تكتب React اصطلاحي بلا memoization صريح، ويحوّل المُجمِّع مصدرك. دالة مثل 'function Cart({ items }) { const total = items.reduce((s, i) => s + i.price, 0); return <Total amount={total} />; }' تُجمَّع إلى نسخة تخزّن 'total' عبر عمليات الرَنْدَرة كلما كانت 'items' مستقرة مرجعيًا. لا يرى المطور هذا أبدًا — يكتب كودًا نظيفًا ويشحن فقط.

على benchmark عدّاد اصطناعي — النوع الذي يبنيه فريق SolidJS لإيصال نقطة — SolidJS أسرع نحو 3 مرات من React مع المُجمِّع مفعّلًا. على إعادة رَنْدَرة لوحة قيادة واقعية بـ 200 مكون، تتقلص الفجوة إلى نحو 1.4 مرة. على منتج حقيقي، من النوع الذي نشحنه لعملاء في ديفيا سوليوشنز، كانت الفجوة مهملة بعد احتساب زمن الشبكة وأوقات استجابة قاعدة البيانات وبقية كومة الطلب. سرعة الرَنْدَرة الخام نادرًا ما تكون العامل المهيمن في الأداء الفعلي الذي يدركه المستخدم.

تكلفة النظام البيئي لـ signals حقيقية ومُقلَّل من تقديرها غالبًا. اختيار signals يعني مغادرة نظام React البيئي، مما يعني إعادة تقييم التوجيه وجلب البيانات والرسوم البيانية ومكتبات الحركة ومكونات نظام التصميم ومراقبة الأخطاء وأدوات الإتاحة — وأهم متزايد في 2026 — مساعد LLM للكود الذي يستخدمه فريقك. معظم LLMs في 2026 تُولّد اصطلاحات React افتراضيًا، لأن React لديها بيانات تدريب أكثر بشكل كبير على الإنترنت العام. أثر 'الزميل الخفي' للتطوير المدعوم بالذكاء الاصطناعي حقيقي وذو معنى، واختيار إطار أقل شيوعًا يعني كتابة المزيد من الكود بنفسك.

هناك عدم تناظر في تجربة المطور تفوتها المقاييس. أُطر signals تجعل رسم التفاعلية قابلًا للقراءة — يمكنك النظر إلى مكون والتفكير في ما يُعاد رَنْدَرته. React مع المُجمِّع تطلب منك الثقة بأن المُجمِّع فعل الشيء الصحيح، وهو يفعل عادة، لكن تنقيح الحالات التي لم يفعل فيها يتطلب أدوات لا تزال تنضج. للمهندسين الكبار المرتاحين مع نظام React البيئي، هذه مقايضة عادلة؛ للفرق التي تستقبل مهندسين مبتدئين، نموذج signals أسهل فعلًا في التعليم.

نصيحة عملية بناءً على الارتباطات التي شحنّاها: للمشاريع الجديدة حيث الأداء حاسم والفريق صغير وعرض النظام البيئي أقل أهمية — Solid أو Svelte 5 هي الإجابة الصحيحة. للمشاريع الجديدة حيث سرعة المنتج مهمة ويحتاج الفريق للتوظيف والتكامل والشحن السريع — React مع المُجمِّع هي الإجابة الصحيحة، وميزة السرعة تتراكم. لتطبيقات React القائمة، تبنّى React Compiler هذا الربع بغض النظر. المكاسب مجانية ولا توجد تكلفة هجرة.

هناك خيار ثالث يستحق المعرفة: إذا أردت دلالات signals داخل قاعدة كود React، انظر إلى تكامل @preact/signals-react. يمنحك تفاعلية دقيقة الحبيبية للمسارات الساخنة دون مغادرة النظام البيئي، ويتركّب بنظافة مع بقية كود React. نستخدمه على لوحات القيادة وأسطح البيانات الحية حيث تواتر إعادة الرَنْدَرة عالٍ بما يكفي ليُهم.

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

بالنظر للأمام، توقّع المزيد من التلاقح المتبادل. مُجمِّع React سيدمج على الأرجح بدائيات شبيهة بـ signals للحالات التي لا يستطيع التحليل الثابت التعامل معها. ستواصل أُطر signals سدّ فجوة النظام البيئي. بحلول 2027، الفارق العملي بين 'React مع المُجمِّع' و'إطار Signals' سيكون أصغر من الفارق العملي بين 'تطبيق بنظام تصميم صارم' و'تطبيق بدونه'. استثمر وفقًا لذلك.

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

نُشر هذا المقال أصلًا على معرض أعمالي الشخصي على eng-ahmed.com/blog/signals-vs-react-compiler-2026 ومنشور بشكل متقاطع على Dev.to (dev.to/ahmedmahmoudabouraia/signals-vs-react-compiler-the-fine-grained-reactivity-showdown-2d0j) وHashnode (engahmed.hashnode.dev) وMedium. لمزيد من كتابات معمارية الواجهة الأمامية، تابعني على eng-ahmed.com أو تعرّف كيف نشحن React الإنتاجي على devya.dev.