المؤلف:
    إنشاء:2026-04-20آخر تحديث:2026-05-18

    مكتبات i18n لـ Solid - تقرير التقييم القياسي 2026

    هذه الصفحة هي تقرير تقييم قياسي لحلول i18n على Solid.

    جدول المحتويات

    التقييم القياسي التفاعلي

    مرجع النتائج:

    intlayer.org
    شاهد بيانات المقارنة الكاملة

    راجع مستودع التقييم القياسي الكامل هنا.

    مقدمة

    تعد حلول التدويل من بين أثقل الاعتمادات في تطبيق Solid. الخطر الرئيسي هو شحن محتوى غير ضروري: ترجمات لصفحات أخرى ولغات أخرى في حزمة مسار واحد.

    مع نمو تطبيقك، يمكن أن تؤدي هذه المشكلة بسرعة إلى تضخم ملفات JavaScript المرسلة إلى العميل وإبطاء التنقل.

    في الممارسة العملية، بالنسبة للتطبيقات الأقل تحسينًا، يمكن أن ينتهي الأمر بصفحة مدولة لتكون أثقل بعدة مرات من النسخة بدون i18n.

    التأثير الآخر هو على تجربة المطور (DX): كيفية التصريح عن المحتوى، والأنواع، وتنظيم فضاء الأسماء، والتحميل الديناميكي، والتفاعل عند تغيير اللغة.

    TL;DR

    • Intlayer: الخيار الموصى به لتطبيقات Solid المهنية التي تحتاج إلى ميزات متقدمة وتحسين (v8.7.12).
    • @solid-primitives/i18n: بديل خفيف الوزن ممتاز للمشاريع البسيطة، على الرغم من افتقاره إلى ميزات متقدمة مثل التحميل الكسول (lazy loading).
    • solid-i18next: خيار معياري ولكنه ثقيل (~4.7 أضعاف Intlayer) مع نفس عيوب React i18next.
    • Paraglide: نهج مبتكر ولكن DX معقد ومشكلات في التخلص من الكود غير المستخدم (tree-shaking) في بعض الإعدادات.

    اختبر تطبيقك

    لتحديد مشكلات تسرب i18n بسرعة، قمت بإعداد ماسح ضوئي مجاني متاح هنا.

    intlayer.org

    المشكلة

    هناك ركيزتان أساسيتان للحد من تكلفة تطبيق متعدد اللغات:

    • تقسيم المحتوى حسب الصفحة / فضاء الأسماء حتى لا يتم تحميل قواميس كاملة عندما لا تحتاج إليها.
    • تحميل اللغة الصحيحة ديناميكيًا، فقط عند الحاجة إليها.

    فهم القيود التقنية لهذه الأساليب:

    التحميل الديناميكي

    بدون التحميل الديناميكي، تحتفظ معظم الحلول بالرسائل في الذاكرة منذ الريندر الأول، مما يضيف عبئًا كبيرًا للتطبيقات التي تحتوي على العديد من المسارات واللغات.

    مع التحميل الديناميكي، فإنك تقبل بمقايضة: ملفات JS أولية أقل، ولكن أحيانًا طلب إضافي عند تبديل اللغة.

    تقسيم المحتوى (Splitting)

    تعتبر الصيغ المبنية حول t('a.b.c') مريحة للغاية ولكنها غالبًا ما تشجع على الاحتفاظ بكائنات JSON كبيرة أثناء التشغيل. هذا النموذج يجعل التخلص من الكود غير المستخدم (tree-shaking) صعبًا ما لم توفر المكتبة استراتيجية حقيقية لتقسيم المحتوى لكل صفحة.

    منهجية البحث

    في هذا التقييم القياسي، قارنا المكتبات التالية:

    • Base App (بدون مكتبة i18n)
    • solid-intlayer (v8.7.12)
    • @solid-primitives/i18n (v2.2.1)
    • solid-i18next (v17.0.2)
    • @inlang/paraglide-js (v2.17.0)

    الإطار هو Solid مع تطبيق متعدد اللغات يتكون من 10 صفحات و 10 لغات.

    قارنا بين أربع استراتيجيات تحميل:

    الاستراتيجية بدون فضاء أسماء (عام) مع فضاء أسماء (محدد/scoped)
    التحميل الثابت Static: كل شيء في الذاكرة عند بدء التشغيل. Scoped static: مقسم حسب فضاء الأسماء؛ يتم تحميل كل شيء عند البدء.
    التحميل الديناميكي Dynamic: تحميل عند الطلب حسب اللغة. Scoped dynamic: تحميل دقيق حسب فضاء الأسماء واللغة.

    ملخص الاستراتيجيات

    • ثابت (Static): بسيط؛ لا يوجد تأخير في الشبكة بعد التحميل الأولي. الجانب السلبي: حجم حزمة كبير.
    • ديناميكي (Dynamic): يقلل الوزن الأولي (تحميل كسول). مثالي عندما يكون لديك العديد من اللغات.
    • ثابت بنطاق (Scoped static): يحافظ على تنظيم الكود (فصل منطقي) بدون طلبات شبكة إضافية معقدة.
    • ديناميكي بنطاق (Scoped dynamic): أفضل نهج لتقسيم الكود والأداء. يقلل من استخدام الذاكرة عن طريق تحميل ما تحتاجه الرؤية الحالية واللغة النشطة فقط.

    ما قمت بقياسه:

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

    • حجم مكتبة الترجمة: بعد التجميع والتخلص من الأغصان والتصغير، فإن حجم مكتبة i18n هو حجم المزودين + رمز الخطافات/البدائل في مكون فارغ. لا يشمل تحميل ملفات الترجمة. يجيب على سؤال ما مدى تكلفة المكتبة قبل دخول المحتوى الخاص بك.

    • JavaScript لكل صفحة: لكل مسار مقارنة، كم من البرنامج النصي يسحبه المتصفح في هذه الزيارة، بمتوسط عبر الصفحات في المجموعة (وعبر المنطقات التي حيث تجميع التقارير). الصفحات الثقيلة هي صفحات بطيئة.

    • تسريب من المناطق الأخرى: إنه محتوى نفس الصفحة ولكن بلغة أخرى الذي سيتم تحميله بالخطأ في الصفحة المراجعة. هذا المحتوى غير ضروري ويجب تجنبه. (على سبيل المثال، محتوى صفحة /fr/about في حزمة صفحة /en/about)

    • تسريب من المسارات الأخرى: نفس الفكرة بخصوص الشاشات الأخرى في التطبيق: ما إذا كان نصها يسير جنبًا إلى جنب عندما فتحت صفحة واحدة فقط. (على سبيل المثال، محتوى صفحة /en/about في حزمة صفحة /en/contact). تشير درجة عالية إلى تقسيم ضعيف أو حزم واسعة جدًا.

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

    • استجابة تبديل اللغة: أقوم بقلب اللغة باستخدام عنصر التحكم الخاص بالتطبيق وأقيس المدة التي يستغرقها حتى تتغير الصفحة بوضوح، وهو ما سيلاحظه الزائر، وليس خطوة دقيقة في المختبر.

    • عمل الرسم بعد تغيير اللغة: متابعة أضيق: مقدار الجهد الذي استغرقته الواجهة لإعادة الطلاء للغة الجديدة بمجرد تطبيق المبدل. مفيد عندما يختلف وقت "الشعور" وتكلفة الإطار العمل.

    • وقت تحميل الصفحة الأولية: من التنقل إلى المتصفح الذي يعتبر الصفحة محملة بالكامل للسيناريوهات التي اختبرتها. جيد للمقارنة بين البدايات الباردة.

    • وقت الترطيب: عندما يكشف التطبيق عنه، المدة التي يقضيها العميل في تحويل HTML من الخادم إلى شيء يمكنك فعلاً النقر عليه. يعني الشرطة في الجداول أن هذا التطبيق لم يوفر رقم ترطيب موثوق في هذا المعيار.

    نجوم GitHub

    تعد نجوم GitHub مؤشرًا قويًا على شعبية المشروع وثقة المجتمع وأهميته على المدى الطويل. على الرغم من أنها ليست مقياسًا مباشرًا للجودة التقنية، إلا أنها تعكس عدد المطورين الذين يجدون المشروع مفيدًا ويتابعون تقدمه ومن المحتمل أن يتبنوه. لتقدير قيمة المشروع، تساعد النجوم في مقارنة الجاذبية عبر البدائل وتوفر رؤى حول نمو النظام البيئي.

    Star History Chart

    النتائج بالتفصيل

    1 - حلول يجب تجنبها

    لا يوجد حل واضح يجب تجنبه في نظام Solid البيئي.

    2 - حلول مقبولة

    (solid-i18next) (solid-i18next@17.0.2):

    ربما يكون solid-i18next هو الخيار الأكثر شيوعًا لأنه كان من أوائل الحلول التي لبت احتياجات i18n لتطبيقات JavaScript. كما أنه يحتوي على مجموعة واسعة من المكونات الإضافية للمجتمع لمشكلات محددة.

    الحزمة ثقيلة (~14.6kb، أي حوالي 4.7 أضعاف solid-intlayer).

    ومع ذلك، فإنه يشترك في نفس العيوب الرئيسية مثل الحلول المبنية على t('a.b.c'): التحسينات ممكنة ولكنها تستهلك الكثير من الوقت، والمشاريع الكبيرة تكتنفها مخاطر الممارسات السيئة (فضاءات الأسماء + التحميل الديناميكي + الأنواع).

    (@solid-primitives/i18n) (@solid-primitives/i18n@2.2.1):

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

    (Paraglide) (@inlang/paraglide-js@2.17.0):

    يقدم Paraglide نهجًا مبتكرًا ومدروسًا جيدًا. ومع ذلك، في هذا التقييم القياسي، لم يعمل tree-shaking الذي تعلن عنه شركتهم مع التنفيذ الخاص بي. سير العمل و DX أيضًا أكثر تعقيدًا من الخيارات الأخرى. شخصيًا، لا أحب الاضطرار إلى إعادة إنشاء ملفات JS قبل كل عملية push، مما يخلق خطرًا مستمرًا لتعارض الدمج عبر طلبات السحب. أخيرًا، مقارنة بالحلول الأخرى، لا يستخدم Paraglide مخزنًا (مثل Solid signal) لاسترداد اللغة الحالية لريندر المحتوى. لكل عقدة يتم تحليلها، سيطلب اللغة من localStorage / cookie وما إلى ذلك. يؤدي هذا إلى تنفيذ منطق غير ضروري يؤثر على تفاعل المكونات.

    3 - التوصيات

    (Intlayer) (solid-intlayer@8.7.12):

    لن أحكم شخصيًا على solid-intlayer من أجل الموضوعية، لأنه الحل الخاص بي.

    ملاحظة شخصية

    هذه الملاحظة شخصية ولا تؤثر على نتائج التقييم القياسي. ومع ذلك، في عالم i18n غالبًا ما ترى إجماعًا حول نمط مثل const t = useTranslation('xx') + <>{t('xx.xx')}</> للمحتوى المترجم.

    في تطبيقات Solid، يعد حقن وظيفة كـ JSX.Element في نظري نمطًا مضادًا (anti-pattern). كما أنه يضيف تعقيدًا يمكن تجنبه وعبئًا في تنفيذ JavaScript (حتى لو كان بالكاد يلاحظ).