أمضى عالم تطوير الويب جزءاً كبيراً من العقد الماضي في إقناع نفسه بأن المتصفح يجب أن يتولى المهام الشاقة. بدأنا بالوثائق والنماذج، ثم انتقلنا بثبات لنقل كل عملية يمكن تصورها إلى جانب العميل (client). التوجيه (Routing)، وإدارة الحالة (state management)، وجلب البيانات (data fetching)، ومنطق العرض (rendering logic)، وحتى تنسيق استعلامات قواعد البيانات عبر GraphQL — انتقل كل ذلك إلى حزم JavaScript التي تزداد ثقلاً مع كل إصدار جديد. تضاعفت أطر العمل، وتعمقت خطوط بناء البرمجيات (build pipelines)، وما بدأ كوسيلة لجعل التطبيقات تبدو سريعة الاستجابة تحول إلى بنية معمارية لا يمكن فيها للصفحة عرض بكسل واحد ذي معنى حتى يتم تنزيل ميجابايتات من الكود وتحليلها وتنفيذها.
لقد حل هذا التحول مشكلات حقيقية؛ فالصفحات التي يتم عرضها من جهة الخادم (Server-rendered) مع لمسة بسيطة من jQuery كانت تكافح لتقديم الانتقالات السلسة التي تشبه التطبيقات والتي يتوقعها المستخدمون. كما منحتنا تطبيقات الصفحة الواحدة (Single Page Applications) تنقلاً فورياً، وحالة مستمرة، وتفاعلات غنية. لكن التكلفة تراكمت؛ ففرق العمل الآن تدير مخازن حالة معقدة في جانب العميل، وتتعامل مع حزم JavaScript ضخمة، وتحافظ على طبقات مزامنة بيانات دقيقة، وتصلح أخطاء خطوط بناء البرمجيات التي تبدو أحياناً وكأنها وظيفة كاملة بحد ذاتها. لقد استبدلنا مجموعة من المشكلات بمجموعة أخرى، ويتساءل العديد من المطورين الآن عما إذا كان كل تطبيق يحتاج حقاً لدفع تلك الضريبة.
هناك تطوران يجعلان الإجابة على هذا السؤال أسهل.
HTMX وعودة الوسائط الفائقة (Hypermedia)
الأول هو HTMX. للوهلة الأولى، يبدو كمكتبة صغيرة، لكن أثره المعماري كبير. يعامل HTMX لغة HTML كصيغة أصلية لمنطق التطبيق، بدلاً من معاملتها كغلاف ثابت يجب ملؤه بواسطة JavaScript.
إليك ما يتغير من الناحية العملية. تقليدياً، عندما ينقر المستخدم على زر لتحميل المزيد من التعليقات، يقوم الجزء الأمامي (frontend) بإرسال طلب fetch، ويتلقى حمولة JSON، ويسويتها في مخزن من جهة العميل، ثم يمررها عبر قالب مكون (component template)، ويجري عملية مقارنة الـ virtual DOM، وأخيراً يقوم بتحديث الصفحة (patching). يقوم HTMX باختصار هذه السلسلة؛ فالزر نفسه يحتوي على سمات (attributes) تخبر المتصفح بمكان إرسال الطلب وعنصر الصفحة الذي يجب استبداله. يعيد الخادم جزءاً من HTML — مجرد التعليقات الجديدة، مغلفة داخل div. يقوم المتصفح باستبدالها فوراً. لا يوجد JSON، ولا شجرة حالة للواجهة الأمامية، ولا خوارزمية توفيق (reconciliation algorithm)، ولا JavaScript أمرية لإبقاء واجهة المستخدم متزامنة مع الخادم.
هذا ليس رفضاً للتطوير الحديث، بل هو رفض للتجريد غير الضروري. يثبت HTMX أن الوسائط الفائقة (hypermedia) — وهو الأسلوب المعماري الذي دفع الويب في بداياته — لا تزال قادرة على دعم واجهات متطورة عند اقترانها ببيئة عمل حديثة. يمكن لأي عنصر إصدار طلبات، وليس فقط النماذج والروابط. يمكن لأي حدث أن يطلق تحديثاً. ويظل الخادم هو المصدر الوحيد للحقيقة (source of truth) لكل من البيانات والعرض.
التحديثات الجزئية التصريحية (Declarative Partial Updates) في Chrome
التحول الثاني أحدث، وهو موجود داخل المتصفح نفسه. يقدم Chrome ميزة التحديثات الجزئية التصريحية، أو DPU. تسمح هذه الميزة للمتصفح ببث HTML وإدراجه مباشرة في أجزاء مستهدفة من الصفحة فور وصول البايتات.
قبل DPU، إذا كنت تريد بث بيانات مباشرة في صفحة ويب، فكنت تلجأ عموماً إلى WebSockets، أو Server-Sent Events، أو long-polling مقترناً بالتلاعب اليدوي بالـ DOM. كان على الواجهة الأمامية إدارة الاتصال، وتحليل الحمولة، وتحديد كيفية ومكان حقن وسم HTML بدقة. يغير DPU هذه المعادلة بجعل العملية تصريحية (declarative)؛ حيث يحدد المطور حاوية مستهدفة، ويتولى المتصفح الباقي: استقبال البث، وتحليل الجزء، ووضعه تماماً حيث ينتمي، حتى قبل إغلاق الاستجابة الكاملة.
فكر في لوحة تحكم للمراقبة تعرض سجلات الخادم أو طابور دعم يتحدث في الوقت الفعلي. مع DPU، يرسل الجزء الخلفي (backend) قطع HTML بسيطة أثناء إنشائها. يقوم المتصفح ببثها في جسم جدول أو حاوية تغذية دون سطر واحد من منطق البث في جانب العميل. عملية التجميع تحدث بشكل أصلي (natively).
نموذج الخادم أولاً (The Server-First Model)
عند الجمع بين HTMX و DPU، تحصل على بنية معمارية متماسكة حيث يمتلك الخادم الحالة ويقوم بتوليد واجهة المستخدم، بينما يتولى المتصفح العرض وإدخالات المستخدم. تصبح أطر عمل الخلفية (Backend frameworks) مثل Rails، وLaravel، وDjango، وGo templates، أو ASP.NET هي طبقة الواجهة الأساسية مرة أخرى. الواجهة الأمامية ليست تطبيقاً منفصلاً يستهلك واجهة برمجة تطبيقات (API)، بل هي واجهة الوسائط الفائقة التي ينتجها الخادم.
يناسب هذا النموذج شريحة واسعة بشكل مفاجئ من البرمجيات. لننظر إلى تطبيقات SaaS النموذجية؛ فهي عبارة عن لوحات تحكم تحتوي على جداول قابلة للفرز، ولوحات تحكم إدارية تحتوي على نماذج وفلاتر، وأدوات داخلية تنقل السجلات من حالة إلى أخرى، وسير عمل CRUD التي تعرض قائمة، وتظهر عرضاً تفصيلياً، وتسمح للمستخدم بتعديل الحقول. بل وحتى واجهات الذكاء الاصطناعي حيث يقوم نموذج لغوي ببث tokens إلى المستخدم، ويمكن تغليف كل token أو فقرة بـ HTML وإضافتها إلى سلسلة المحادثة. بالنسبة لكل هذه الحالات، غالباً ما يكون وجود عميل JavaScript ثقيل أمراً مبالغاً فيه.
الفوائد فورية وعملية. عمليات تحميل الصفحة الأولية أسرع لأن أول رسم ذي معنى (first meaningful paint) يصل كـ HTML، وليس بعد اكتمال دورة الـ hydration. تتقلص أحجام حمولات JavaScript لأنه لا يوجد virtual DOM، ولا موجه (router) من جهة العميل، ولا مكتبة لإدارة الحالة (state management) ليتم إرسالها. ترى محركات البحث محتوى كاملاً دون الحاجة لتنفيذ الحزم (bundles)، لذا يعمل الـ SEO بشكل تلقائي. تنخفض التعقيدات لأن قاعدة كود واحدة تتعامل مع التوجيه (routing)، ومنطق العمل (business logic)، والتحويل إلى واجهة (rendering). تصبح عملية تصحيح الأخطاء (debugging) أسهل؛ فعندما يبدو شيء ما خاطئاً، يمكنك فحص علامة تبويب Network ورؤية الـ HTML الذي أرسله الخادم بالضبط، دون وجود كائن حالة (state object) غامض من جهة العميل يحتاج إلى هندسة عكسية.
ماذا عن React والعملاء الثقلاء؟
لا يعني أي من هذا أن React قد انتهى، أو أن تطبيقات SPA هي خطأ. لا تزال التطبيقات المعقدة ذات المستوى الاحترافي (editor-grade) بحاجة إلى عميل ثقيل. يقوم Figma بتشغيل محرك C++ تم تجميعه إلى WebAssembly داخل المتصفح لأن رحلات الذهاب والإياب إلى الخادم (server round-trips) ستجعل الرسم مستحيلاً. يقوم Canva بمعالجة الـ canvas بمعدل ستين إطاراً في الثانية باستخدام الهندسة من جهة العميل. يستخدم Google Docs تقنية operational transforms لحل تعارضات التحرير في أجزاء من الثانية. هذه الأدوات هي في الأساس تطبيقات سطح مكتب يتم تقديمها عبر علامة تبويب في المتصفح، وهي لن تعود إلى النماذج التي يتم عرضها من جهة الخادم (server-rendered forms).
لكن معظم البرمجيات ليست Figma. معظم البرمجيات ليست محررات رسومات في الوقت الفعلي. معظم البرمجيات هي شاشة تقارير، أو لوحة إعدادات، أو مسار حجز، أو نموذج إدارة محتوى. بالنسبة لهذا الجزء الطويل من التطبيقات، لم يكن إرسال مئات الكيلوبايتات من إطار عمل JavaScript لمجرد تبديل نافذة منبثقة (modal) أو جلب قائمة سجلات أمراً منطقياً على الإطلاق. إن اقتصاديات البنية التقنية (stack) تتغير؛ فنحن نعيد اكتشاف أن الخادم يمكن أن يكون قريباً من المستخدم بفضل الـ edge، وأن المتصفح نفسه أصبح قادراً بما يكفي لتحديث الأجزاء (fragments) دون الحاجة إلى إطار عمل يتوسط كل بايت.
البندول يجد توازناً
قوس بنية الويب يتأرجح عائداً نحو البساطة، لكنه ليس عودة ساذجة إلى التسعينيات. المتصفح أصبح أكثر ذكاءً. الميزات مثل DPU لا تحل محل براعة المطورين؛ بل تستوعب الأنماط التي كنا نطبقها يدوياً — مثل البث (streaming)، والتحديثات الجزئية، وإدراج DOM المستهدف — داخل المنصة نفسها. يمنحنا HTMX المفردات للتعبير عن تلك السلوكيات دون إعادة بناء نظام تشغيل مصغر في الواجهة الأمامية (frontend).
لم يعد عليك الاختيار بين بنية بسيطة وتجربة مستخدم سريعة الاستجابة؛ يمكنك الحصول على كليهما. يمكن للخادم أن يقود الواجهة، ويمكن للمتصفح تجميعها، ويمكن لـ JavaScript الذي تكتبه أن يركز على التفاعل الحقيقي بدلاً من الأعمال التأسيسية (plumbing).
بالنسبة للجيل القادم من لوحات التحكم، والأدوات الإدارية، وواجهات الذكاء الاصطناعي، قد يكون العميل الأذكى هو ذلك الذي يقوم بعمل أقل.
