“ليس السؤال ما إذا كنت ستبني تطبيقك، بل كيف ستبنيه، وبأي أداة ستحقق أفضل نتيجة بأقل تكلفة وأعلى كفاءة.”
في عالم تطوير تطبيقات الهواتف المحمولة سريع التطور، يواجه المطورون والشركات قراراً حاسماً: ما هي التقنية الأفضل لبناء تطبيقهم القادم؟ هل نعتمد على الأداء القوي للتطوير الأصلي (Native)، أم سرعة التطوير التي يوفرها Flutter، أم الحل الوسط الذي تقدمه منصة Kotlin المتعددة (KMP)؟
ففي جلسة Mobile Dev Meetup في نيسان 2025 كان هذا هو محور الجلسة العاشرة من لقاءات المجتمع الشهرية، فقد كان فيها الدليل لاتخاذ قرار مستنير، حيث غاصت المهندسة سدرة مرخان في أعماق كل تقنية، وقارنت بينها بناءً على عوامل رئيسية مثل الأداء وسرعة التطوير والوصول لميزات النظام.
الفهرس:
- من أين بدأ الاختلاف؟ وما هو المترجم (Compiler)؟
- إطار العمل Flutter.
- التطوير الأصلي (Native): القوة المطلقة والتحكم الكامل.
- Kotlin Multiplatform (KMP) الحل الوسط الذكي.
- العوامل الأساسية لاختيار إطار العمل.
- متى تختار كل تقنية؟
محاور الجلسة
أولاً: ما هو المترجم (Compiler)؟
المترجم كأبسط تعريف له، كمترجم اللغات البشرية، يقوم تحويل النص من لغة إلى لغة أخرى، (من اللغة البرمجية الى لغة نظام التشغيل – الأصفار والواحدات – وعندها يستطيع نظام التشغيل تنفيذ البرنامج المكتوب)
تطورت هذه الأداة (المترجم) وأصبحت تعتمد أساليب ومعماريات مختلفة منها:
التنفيذ الآني (JIT : Just In Time)
“التنفيذ في الوقت المناسب” يعني “تنفيذ ما هو مطلوب فقط، في الوقت المناسب، وبالكمية المطلوبة”.
ويحاول المترجم هذا التنبؤ بالتعليمات التي سيتم تنفيذها لاحقاً، مما يسمح بتجميع الأسطر البرمجية مُسبقًا.
التنفيذ المُسبق (AOT : Ahead Of Time)
يعمل مترجم AOT على تجميع الشفرة قبل “تسليمها” إلى أي بيئة تشغيل تُشغّلها.
مقارنة بين الأسلوبين:
| وجه المقارنة | التنفيذ الآني (JIT) | التنفيذ المُسبق (AOT) |
|---|---|---|
| سرعة بدء التشغيل | أبطأ، لأن الترجمة تحدث أثناء بدء تنفيذ البرنامج. | أسرع، لأن الكود مترجم بالكامل وجاهز للتنفيذ. |
| أداء وقت التشغيل | ديناميكي، يمكنه تحسين أداء الأجزاء الأكثر استخداماً من الكود بشكل مستمر. | ثابت، الأداء مُحسَّن مسبقاً ولا يتكيف مع أنماط الاستخدام الفعلية. |
| استهلاك الذاكرة | أعلى، لوجود الشيفرة الوسيطة والشيفرة المترجمة في الذاكرة معاً. | أكثر كفاءة، حيث تُستخدم شيفرة الآلة المترجمة فقط. |
| المرونة | أكثر مرونة، يسمح بالتحسينات الديناميكية بناءً على الاستخدام الحقيقي. | أقل مرونة، لأن جميع التحسينات تتم مسبقا ولا تتكيف أثناء التشغيل. |
| الحمل الزائد أثناء التشغيل | يسبب حملاً زائدا بسبب عملية الترجمة المستمرة أثناء التنفيذ. | لا يوجد حمل زائد متعلق بالترجمة، مما يؤدي إلى أداء أكثر استقراراً. |
ثانياً: إطار العمل Flutter:
يتميز Flutter بقدرته على تحقيق توازن فريد بين سرعة التطوير والأداء القوي، وهذا يعود بشكل أساسي إلى كيفية ترجمة وتشغيل الكود.
JIT مقابل AOT: سر قوة Flutter
لفهم أداء Flutter، يجب أن نعرف الفرق بين نوعين من المترجمات (Compilers):
- JIT (Just-In-Time): يُستخدم في وضع التطوير (Debug Mode). يقوم بترجمة الكود أثناء تشغيل التطبيق، مما يسمح بميزة “Hot Reload” التي تعكس التغييرات في الواجهة فوراً دون الحاجة لإعادة تشغيل التطبيق بالكامل.
- AOT (Ahead-Of-Time): يُستخدم في وضع الإنتاج (Release Mode). يقوم بترجمة كود Dart بالكامل إلى كود أصلي (Native ARM code) قبل إطلاق التطبيق. هذا يعني أن التطبيق يعمل مباشرة على معالج الجهاز دون الحاجة إلى طبقات وسيطة، مما يمنحه سرعة فائقة وبصمة ذاكرة أقل.
على عكس أطر عمل أخرى مثل React Native التي تعتمد على “جسر” (Bridge) للتواصل بين JavaScript والكود الأصلي، يتجنب Flutter هذه الطبقة الإضافية، مما يؤدي إلى أداء أفضل ورسوم متحركة أكثر سلاسة.
محرك العرض: من Skia إلى Impeller
يعتمد Flutter على محركه الخاص لعرض الواجهات بكسل ببكسل، مما يمنحه تحكما كاملاً ومظهراً متسقاً عبر جميع المنصات.
- Skia: هو محرك رسوميات ثنائي الأبعاد مكتوب بلغة C++ كان المحرك الأساسي في Flutter.
- Impeller: هو محرك العرض الجديد الذي حل محل Skia، وهو مصمم خصيصاً لـ Flutter. الميزة الكبرى في Impeller هي أنه يقوم بترجمة التظليلات (Shaders) مسبقاً بدلاً من ترجمتها أثناء التشغيل. هذا التغيير يقضي على مشكلة “التقطيع” (Jank) التي كانت تحدث أحياناً مع Skia، ويضمن أداءً أكثر استقراراً وسلاسة.
ثالثاً: التطوير الأصلي (Native): القوة المطلقة والتحكم الكامل
يبقى التطوير الأصلي (لكل من Android و iOS) المعيار الذهبي عندما يتعلق الأمر بالأداء والوصول المباشر إلى إمكانيات الجهاز.
كيف يعمل Android: تطور ART
تطور وقت تشغيل أندرويد (Android Runtime) بشكل كبير:
- Dalvik (قبل أندرويد 5.0): كان يستخدم مترجم JIT فقط، مما كان يؤدي إلى تباطؤ في التنفيذ.
- ART (أندرويد 5.0 وما بعده): بدأ باستخدام مترجم AOT، حيث يتم تجميع التطبيق بالكامل عند تثبيته، مما أدى إلى تنفيذ أسرع للتطبيقات.
- النهج الهجين (أندرويد 7.0 وما بعده): يجمع ART الآن بين JIT و AOT من خلال تقنية تُعرف بـ Profile-Guided Optimization (PGO). عند تشغيل التطبيق لأول مرة، يعمل مترجم JIT. في الخلفية، يقوم ART بتسجيل الأجزاء الأكثر استخداماً من الكود (“hot paths”) ويقوم بترجمتها مسبقاً (AOT) عندما يكون الجهاز في وضع الخمول، مما يجمع بين سرعة بدء التشغيل الأول والأداء المحسّن في عمليات التشغيل اللاحقة.
| الجانب | Flutter (Dart) | Native Android (ART + Kotlin/Java) | Native iOS (Swift/Obj-C) |
|---|---|---|---|
| وقت بدء التشغيل | أبطأ قليلاً بسبب تهيئة محرك Flutter. | سريع (محسّن بفضل PGO). | سريع جدًا (AOT فقط). |
| الأداء | أبطأ قليلاً من الأصلي بسبب طبقة المحرك. | يتم تحسينه بمرور الوقت (JIT+AOT). | مُحسَّن للغاية (أصلي بالكامل). |
| حجم التطبيق | أكبر (يشمل محرك Flutter ووقت تشغيل Dart). | أصغر (ملفات ثنائية أصلية). | أصغر (ملفات ثنائية محسّنة بالكامل). |
| الوصول للعتاد | يعتمد على إضافات (Plugins)، وقد يتطلب Platform Channels للميزات المتقدمة. | وصول مباشر ومحسّن لواجهات برمجة تطبيقات النظام والعتاد. | وصول مباشر ومحسّن لواجهات برمجة تطبيقات النظام والعتاد. |
رابعاً: Kotlin Multiplatform (KMP) الحل الوسط الذكي
KMP لا تأتي كبديل للتطوير الأصلي، بل كامتداد له. إنها تقنية تسمح بمشاركة
منطق العمل (Business Logic) بين منصات متعددة (Android, iOS, Web)، مع ترك تطوير واجهة المستخدم (UI) أصلية لكل منصة.
كيف تختلف KMP عن Flutter؟
الفكرة الأساسية لـ KMP مختلفة تماماً عن Flutter. فبينما تهدف Flutter إلى استبدال البرمجة الأصلية بالكامل، تهدف KMP إلى تحسينها.
- لا يوجد محرك إضافي: يعمل KMP مباشرة فوق إطار العمل الأصلي للمنصة دون أي طبقات وسيطة، مما يضمن أداءً أصلياً.
- لا توجد لغة جديدة (للمطوري Android): يستخدم المطورون لغة Kotlin التي يعرفونها بالفعل، ويقوم مترجم Kotlin بتحويل الكود المشترك إلى كود خاص بكل منصة (Java لـ Android، Objective-C لـ iOS).
- المنتج النهائي أصلي 100%: لا يتم تضمين أي كود Kotlin في التطبيق النهائي؛ المنتج يحتوي فقط على الكود الأصلي، تماماً مثل أي تطبيق آخر.
نقاط القوة والضعف
نقاط القوة:
- مرونة في مشاركة الكود: يمكنك اختيار ما تريد مشاركته، سواء كان منطق العمل فقط أو حتى بعض عناصر الواجهة (باستخدام Compose Multiplatform).
- أداء أصلي: لا يوجد أي تدهور في الأداء لأنه يتم تجميعه إلى كود أصلي.
- التكامل السلس: يمكن دمج KMP تدريجياً في المشاريع الحالية دون الحاجة إلى إعادة كتابة التطبيق بالكامل.
نقاط الضعف:
- مكتبات محدودة: لا تزال المكتبات المتاحة أقل مقارنة بـ Flutter، خاصة في مجالات مثل اختبار الكود.
- تكلفة أعلى من Flutter: على الرغم من أنها تقلل الجهد بنسبة تقارب 40%، إلا أنها لا تزال تتطلب بناء واجهات مستخدم منفصلة لنظامي Android و iOS، مما يزيد التكلفة مقارنةً بحلول مثل Flutter.
خامساً: العوامل الأساسية لاختيار إطار العمل
من الضروري تقييم العوامل الرئيسية التي ستؤثر على هذا القرار. ومن أهمها:
- احتياجات المشروع: اختر التطوير الأصلي (Native) إذا كان الأداء الفائق هو الأولوية، بينما توفر أطر العمل متعددة المنصات وصولاً أوسع للجمهور.
- الأداء: التطوير الأصلي هو الخيار الأمثل للمهام التي تتطلب معالجة ثقيلة. أما Flutter، فيقدم أداءً يقترب كثيراً من الأداء الأصلي.
- سرعة التطوير والتكلفة: تساهم أطر العمل مثل Flutter في تقليل وقت وتكلفة التطوير بشكل ملحوظ.
- خبرة الفريق: اختيار التقنية التي يتقنها فريقك يوفر الكثير من الوقت والموارد.
- الصيانة على المدى الطويل: يجب الأخذ في الاعتبار استقرار التقنية، وتيرة التحديثات، وتكاليف الصيانة المستقبلية.
سادساً: متى تختار كل تقنية؟
وهذه خلاصة تساعدك على اتخاذ القرار:
اختر التطوير الأصلي (Native) عندما يكون تطبيقك:
- حرجاً من حيث الأداء: مثل الألعاب المتطورة، تطبيقات الواقع المعزز (AR/VR)، أو تحرير الفيديو.
- يعتمد بشكل كبير على العتاد: يتطلب وصولاً مباشراً وعميقا إلى ميزات مثل البلوتوث، NFC، أو المقاييس الحيوية.
- يحتوي على خدمات تعمل في الخلفية بكثافة: مثل تطبيقات VPN أو مزامنة الملفات.
اختر Flutter عندما يكون تطبيقك:
- متعدد المنصات: الهدف هو بناء تطبيق لنظامي iOS و Android من قاعدة كود واحدة.
- يركز على واجهة المستخدم: الأولوية لتصميم جذاب وتجربة مستخدم غنية.
- يحتاج إلى إطلاق سريع (MVP): مثالي للشركات الناشئة التي ترغب في إطلاق منتجها الأولي بسرعة في السوق.
اختر Kotlin Multiplatform (KMP) عندما:
- لديك تطبيق أصلي حالي: وترغب في مشاركة منطق العمل بين Android و iOS لتقليل تكرار الكود.
- تحتاج إلى أداء أصلي وواجهة مستخدم أصلية: لكنك لا تزال ترغب في الاستفادة من مشاركة الكود.
- شركات مثل Netflix و McDonald’s و Cash App تستخدم KMP بالفعل لتحسين الموثوقية وتقديم الميزات بشكل أسرع.
الختام :
القرار الأمثل يعتمد كليًا على احتياجات مشروعك المحددة، متطلبات الأداء، سرعة التطوير المطلوبة، وخبرة فريقك. بتحديد هذه العوامل بوضوح، ستتمكن من اختيار الإطار الذي سيمكنك من بناء تطبيق ناجح يلبي توقعاتك وتطلعات المستخدمين.
روابط ذات صلة :
- https://www.thedroidsonroids.com/blog/flutter-vs-kotlin-multiplatform
- https://medium.com/flutter-community/flutter-reload-whats-under-the-hood-978bce8af874
- https://medium.com/@elifoksas/android-runtime-art-evolution-and-foundation-of-modern-mobile-app-development-518a68a3ad9c
- https://onuoha.medium.com/how-does-jit-and-aot-work-in-dart-cab2f31d9cb5
ألبوم الصور:
اكتشاف المزيد من Mobile Dev Meetup
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.
السلام عليكم
بالجدول الاول (jit vs AoT)
كانو اخر سطر من الجدول فيه غلط
تمام شكراً للتنبيه .. تم التصحيح