✦هندسة

لماذا اخترنا التطبيقات الأصلية بدل Electron (وسنفعلها مجددًا)

قال لنا الجميع: استخدموا Electron. اكتبوا مرة واحدة وشغّلوا في كل مكان. تحركوا بسرعة. فعلنا العكس — SwiftUI على Apple، وJetpack Compose على Android، وC++/WinRT على Windows، وMetal وVulkan الخامَين حيث احتجنا إلى بكسلات على ساعة دقيقة. إليك ما تعلمناه من بناء أربعة عملاء أصليين لمنتج واحد.

الطريق السهل مقابل الطريق الصحيح

حين تخبر الناس أنك تبني تطبيق سطح مكتب بعيد من الصفر في 2024، فالسؤال الأول دائمًا: «لماذا لا تستخدم Electron؟»

سؤال وجيه. فـ Electron يشغّل بعضًا من أنجح التطبيقات على هذا الكوكب — VS Code وSlack وDiscord وغلاف سطح المكتب لـ Figma. يتيح لك الكتابة مرة واحدة والنشر في كل مكان. ويتحول مطورو الويب لديك إلى مطوري سطح مكتب بين ليلة وضحاها. وميزة سرعة الوصول إلى السوق حقيقية.

نظرنا في الأرقام، ووازنا المقايضات، واخترنا أصعب طريق ممكن: أصلي بالكامل على كل منصة. SwiftUI على iOS وmacOS. وJetpack Compose على Android. وC++/WinRT على Windows. وMetal للعرض على Apple. وVulkan على كل ما عداها. وخادم Go مخصص في القلب.

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

ضريبة Electron حقيقية

لنبدأ بما هو Electron فعلًا: نافذة متصفح Chromium تتظاهر بأنها تطبيق سطح مكتب. وهذا ليس نقدًا — إنه معمارية. وفي كثير من التطبيقات لا بأس به إطلاقًا.

لكن في سطح مكتب بعيد؟ أنت تبثّ بكسلات من حاسوب آخر وتعرضها في الوقت الفعلي بينما تلتقط كل حدث إدخال وترسله عائدًا. زمن الاستجابة ليس ميزة اختيارية. إنه المنتج كله.

إليك ما قسناه حين صنعنا نموذجًا أوليًا للنهجين:

الـ380 ميغابايت ليست تضخّم Electron. إنها Chromium يؤدي عمله — V8 وعملية رسوميات وعمليات مساعدة ومحرك متصفح كامل. إنها هندسة مثيرة للإعجاب. لكنها هندسة صُممت لمشكلة مختلفة.

الإطارات أهم من الميزات

سطح المكتب البعيد من الفئات القليلة من التطبيقات التي يهم فيها كل إطار على حدة. أسقط إطارًا فيشعر المستخدم به. أضف 16 مللي ثانية من زمن استجابة الإدخال فلا يستطيع المصمم رسم منحنيات سلسة. أضف 32 فلا يستطيع اللاعب اللعب.

مع العرض الأصلي نتحدث مباشرة إلى وحدة الرسوميات. وعلى منصات Apple يمنحنا VideoToolbox وصولًا مباشرًا إلى فك ترميز الفيديو عتاديًا. نأخذ إطار H.265 من الشبكة، ونفك ترميزه عتاديًا، ونعرضه — دون أن يلمس الإطار الذاكرة الرئيسية أصلًا. ويعمل مسار فك الترميز إلى العرض في أقل من 4 مللي ثانية على جهاز Mac حديث.

أما في Electron، فيسافر الإطار نفسه عبر مُركِّب Chromium، ثم عبر جسر IPC، ثم تطلي Skia، ثم يركّبه نظام التشغيل مرة أخرى. كل قفزة تضيف زمن استجابة. وكل قفزة تضيف اهتزازًا. والاهتزاز — توقيت الإطارات غير المتسق — هو ما يجعل سطح المكتب البعيد يبدو غير سليم حتى حين يبدو معدل الإطارات في المتوسط جيدًا.

لم نختر الأصلي لنكون متزمتين. اخترناه لأن فيزياء مشكلتنا فرضته — نحو 8 مللي ثانية من المعالجة على الشبكة المحلية (والباقي هو إيقاع تحديث شاشتك الخاص بتردد 60 هرتز) لا يترك مكانًا لمتصفح في المنتصف.

سجل قدرات: الأصلي مقابل الويب

كثيرًا ما يعلق نقاش Electron مقابل الأصلي في الانطباعات. لذلك دوّنّا قدرات نظام التشغيل السبع التي يعتمد عليها Remio في كل ثانية من كل جلسة وسألنا بوضوح: كيف تبلي كل منها تحت كل بيئة تشغيل؟

القدرةالأصليالويب / Electron
فك ترميز عتادي بمعدل 60 إطارًا● VideoToolbox / D3D11VA مباشر○ عبر WebCodecs، مع اهتزاز
صوت USB منخفض زمن الاستجابة● CoreAudio / WASAPI— معزول، 40 مللي ثانية فأكثر
مراقبة إدخال لوحة المفاتيح● CGEvent / SendInput— محجوب خارج التركيز
وصول إلى وحدة الرسوميات عبر Metal / D3D11● مواد نسيجية دون نسخ○ WebGPU، مع قفزات نسخ
نظام الملفات المحلي● كامل، بنطاق يحدده النظام○ منتقٍ فقط، مع مطالبات
نوافذ متعددة وشاشات متعددة● نوافذ أصلية في النظام○ حلول ترقيعية BrowserWindow
الاستمرار في الخلفية● LaunchAgent / خدمة— يُعلَّق عند الإخفاء

كل صف ميزة نشحنها اليوم. وكل — في عمود الويب حل بديل علينا ابتكاره وتوثيقه والاعتذار عنه. فالتطوير الأصلي يعني أننا نعامل تلك القدرات كأوليات لا كحشوات تعويضية.

المواطنة في المنصة

إليك شيئًا نادرًا ما يتحدث عنه أنصار «اكتب مرة وشغّل في أي مكان»: المستخدمون يلاحظون.

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

هذه ليست أمورًا اختيارية. إنها الفرق بين تطبيق يتسامح معه الناس وتطبيق يحبونه. وعلى iOS هذا حرج بشكل خاص — فمراجعة App Store سترفض التطبيقات التي تبدو غير أصلية، وبحق.

مع SwiftUI نحصل على كل هذا مجانًا. حجم النص الديناميكي، وإتاحة VoiceOver، والاهتزازات الحسية للنظام، وتعدد المهام على iPad، واختصارات لوحة المفاتيح على Mac. لا نعيد تنفيذ ميزات المنصة. بل نستخدمها.

الكلفة حقيقية أيضًا

لنكن صادقين بشأن الجانب السلبي: التطوير الأصلي مكلف. ليس بالدولارات — بل بالوقت والتعقيد.

نصون أربع قواعد شيفرة للواجهة. طبقة الشبكات والترميز لدينا مشتركة (Go للإشارات، وC++ لبروتوكول البث)، لكن كل بكسل تراه على الشاشة شيفرة خاصة بالمنصة. وميزة تستغرق يومًا في Electron تستغرق منا من ثلاثة إلى خمسة أيام، لأننا نبنيها أربع مرات، مضبوطة لكل منصة.

مرّت بنا أسابيع عمل فيها تحريك واحد بشكل جميل على iOS، وتعطّل على Android، وكان متعثرًا على Windows. ومصفوفة تصحيح الأخطاء قاسية.

لكن إليك ما تعلمناه: أصعب طريق والطريق الصحيح كثيرًا ما يكونان الطريق نفسه. لا يعرف مستخدمونا معماريتنا ولا يهتمون بها. إنهم يعرفون أن Remio يبدو سريعًا ويبدو سليمًا ولا يلتهم بطاريتهم على الفطور.

هل سنفعلها مجددًا

دون تردد.

منحنا النهج الأصلي أداءً لا يستطيع Electron مجاراته جوهريًا في حالة الاستخدام هذه. ومنحنا تطبيقات تبدو كأنها تنتمي إلى كل منصة. ومنحنا بصمة ذاكرة دون 45 ميغابايت بدل 380. ومنحنا نحو 8 مللي ثانية من المعالجة على الشبكة المحلية (والباقي هو إيقاع تحديث شاشتك الخاص بتردد 60 هرتز)، بينما يقف منافس مغلّف بمتصفح فوق 60 مللي ثانية.

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

هيمنت على فئة سطح المكتب البعيد تطبيقات ويب مغلّفة بـ Electron وتطبيقات أصلية قديمة لم تُحدَّث بشكل ذي معنى منذ سنوات. وهناك مجال لشيء حديث وأصلي معًا — شيء مبني من الصفر مع وضع عتاد اليوم في الحسبان.

هذا هو Remio. مبني بالطريقة الصعبة، لأن بعض الأمور تستحق أن تُنجَز بشكل صحيح.

أيقونة تطبيق Remio

اشعر بالفرق الذي يصنعه الأصلي

Remio مجاني، وأصلي على كل منصة، ومشفّر من طرف إلى طرف. بصمة دون 45 ميغابايت، ونحو 8 مللي ثانية من المعالجة على الشبكة المحلية (والباقي هو إيقاع تحديث شاشتك الخاص بتردد 60 هرتز) — مبني بالطريقة الصعبة ليبدو سليمًا.

مجاني الاستخدامأصلي بنسبة 100%مشفّر من طرف إلى طرف