استخدم مساعدك المفضل للملخص واستخدم هذه الصفحة والموفر AI الذي تريده
تمت ترجمة محتوى هذه الصفحة باستخدام الذكاء الاصطناعي.
اعرض آخر نسخة المحتوى الأصلي باللغة الإنكليزيةإذا كان لديك فكرة لتحسين هذه الوثيقة، فلا تتردد في المساهمة من خلال تقديم طلب سحب على GitHub.
رابط GitHub للتوثيقنسخ الـ Markdown من المستند إلى الحافظة
next-intl مقابل Intlayer: مقارنة أداء التدويل (i18n) في React وNext.js

مكتبة next-intl هي أكثر مكتبات i18n شيوعاً لـ Next.js. وتعتبر Intlayer بديلاً قائماً على المترجم بنطاق محدد على مستوى المكونات. كلاهما يقدم حلول التدويل لتطبيقات App Router. والسؤال الأهم هو ما تكلفة كل منهما بمجرد بناء التطبيق.
هذا المقال ليس دليلاً تعليمياً، بل هو مقارنة مدعومة بالأرقام من Benchmark Bloom، وهو مشروع اختبار مفتوح المصدر يبني التطبيق نفسه مع كل مكتبة ويقيس ما يقوم المتصفح بتنزيله وتنفيذه فعلياً.
tl;dr: في نفس تطبيق Next.js، تضيفnext-intl+12.6 كيلوبايت gzip من JavaScript على كل صفحة، مقابل +0.3 كيلوبايت لـ Intlayer. دون أي عمل إضافي، ترسلnext-intl~90% من سلاسل الصفحات الأجنبية مع كل صفحة. يتطلب الوصول إلى تسريب بنسبة 0% معnext-intlتحديد نطاقات مساحات الأسماء واستخدامpick(messages, [...])لكل صفحة. بينما تصل Intlayer إلى 0% افتراضياً لأن مترجمها يحدد نطاق المحتوى لكل مكون. وإذا كنت تريد واجهة برمجة تطبيقاتnext-intlمع مخرجات Intlayer، فقد سجل محول@intlayer/next-intl147.5 كيلوبايت لكل صفحة مقابل 153.6 كيلوبايت مع المكتبة الأصلية.
نظرة عامة
- next-intl - معيار مجتمع Next.js. قواميس JSON مركزية لكل لغة، دعم كامل لـ ICU MessageFormat، وتكامل وثيق مع معالجة طلبات Next.js ونظام التوجيه الخاص به.
- Intlayer - نموذج محتوى يتمحور حول المكونات. توضع ملفات
.content.tsبجانب مكوناتها، ويقوم مترجم وقت البناء بتقليم الشجرة (tree-shaking) والتحميل الكسول للمحتوى لكل مكون ولكل لغة، مع توليد أنواع TypeScript صارمة تلقائياً.
افتح الجدول في نافذة منبثقة لعرض جميع محتويات البيانات بوضوح
يتم تحديث الشارات تلقائياً.
مقارنة الميزات جنباً إلى جنب
افتح الجدول في نافذة منبثقة لعرض جميع محتويات البيانات بوضوح
| الميزة | Intlayer (react-intlayer / next-intlayer) | next-intl (next-intl / use-intl) |
|---|---|---|
| الترجمات بجانب المكونات | ✅ نعم، ملف .content.ts بجوار كل مكون | ❌ قواميس JSON مركزية في مجلد messages/ |
| التكامل مع TypeScript | ✅ أنواع صارمة مولدة تلقائياً من المحتوى | ⚠️ مدعوم عبر إعدادات global.d.ts يدوية لمسارات الرسائل |
| اكتشاف الترجمات المفقودة | ✅ خطأ TypeScript + خطأ/تحذير وقت البناء | ⚠️ وقت التشغيل يعيد المفتاح أو يرمي خطأ حسب الإعدادات |
| المحتوى الغني (JSX / Markdown / مكونات) | ✅ دعم مباشر | ⚠️ عبر t.rich() مع توفير مكونات التحويل |
| دعم ICU MessageFormat | ⚠️ قيد التطوير | ✅ نعم، دعم كامل لمعيار ICU |
| مكونات الخادم المتزامنة | ✅ useIntlayer من next-intlayer/server يعمل في أي مكون خادم متزامن | ❌ يتطلب تمرير الترجمات عبر الـ props من خادم غير متزامن |
| تقليم الشجرة (Tree-shaking) | ✅ تلقائي لكل مكون ولكل لغة | ⚠️ يتطلب تقسيماً يدوياً لمساحات الأسماء واستخدام pick() |
| التحميل الكسول (Lazy loading) | ✅ سطر إعداد واحد (importMode: 'dynamic') | ⚠️ يتطلب استيراداً ديناميكياً يدوياً في getRequestConfig |
| محرر مرئي / CMS | ✅ محرر مرئي مجاني + CMS اختياري | ❌ لا يوجد |
| ترجمة مدعومة بالذكاء الاصطناعي | ✅ مدمجة وتستخدم مفاتيحك الخاصة | ❌ لا يوجد |
| خادم MCP ومهارات الوكلاء | ✅ نعم | ❌ لا يوجد |
الاختبار
ما تم قياسه
تبني مجموعة Benchmark Bloom نفس التطبيق مع كل مكتبة: 10 صفحات (الرئيسية، من نحن، المدونة، الوظائف، اتصل بنا، الأسئلة الشائعة، الأسعار، المنتجات، الإعدادات، الفريق)، و10 لغات (en، fr، es، de، it، pt، zh، ja, ko, ru)، مع مكونات متطابقة ومحتوى متطابق. يتم قياس الصفحات باللغتين en وfr. يتم تطبيق كل مكتبة في ما يصل إلى أربع استراتيجيات تحميل:
افتح الجدول في نافذة منبثقة لعرض جميع محتويات البيانات بوضوح
| الاستراتيجية | الوصف | من يستخدمها |
|---|---|---|
| static | يتم تجميع كل لغة وكل صفحة معاً وتحميلها دفعة واحدة | النماذج الأولية السريعة، الأكواد المولدة بالذكاء |
| dynamic | يتم تحميل لغة العرض النشطة فقط، ولكن لجميع الصفحات دفعة واحدة | معظم المشاريع |
| scoped-static | مساحات أسماء لكل مسار، بدون تحميل كسول | نادرة |
| scoped-dynamic | مساحات أسماء لكل مسار + تحميل كسول. يتم إرسال الصفحة الحالية باللغة الحالية فقط | التطبيقات ذات الميزانيات الصارمة في الأداء |
لا تملك Intlayer متغيراً "مخصص النطاق" (scoped): يقوم المترجم تلقائياً بتحديد نطاق المحتوى لكل مكون، لذلك فإن صفي static وdynamic محصوران بالفعل.
لكل بناء، تسجل المجموعة:
- حجم المكتبة (Lib size): حجم gzip لمكون فارغ يستورد مكتبة i18n فقط.
- JS للصفحة (Page JS): متوسط حجم JavaScript بتنسيق gzip الذي تم تنزيله لكل صفحة.
- نسبة تسرب اللغة (Locale leak %): نسبة السلاسل التي تنتمي إلى لغة لا يعرضها المستخدم.
- نسبة تسرب الصفحة (Page leak %): نسبة السلاسل التي تنتمي إلى صفحة لا يتصفحها المستخدم.
- متوسط حجم المكون (Component avg): متوسط حجم gzip لكل مكون تم تجميعه بمعزل.
- تفاعلية E2E: الوقت المنقضي بين اختيار لغة جديدة وتحديث
html[lang]في الـ DOM. - الترطيب (Hydration): مدة مرحلة ترطيب React.
الأرقام أدناه مأخوذة من اختبار بتاريخ 2026-09-12 باستخدامnext-intl4.14.2 وintlayer9.5.1.
النتائج على Next.js (App Router)
اختر المقاييس والمكتبات التي تهمك:
المقياس
تحميل JSON الديناميكي
تحميل الترجمات ببطء في وقت التشغيل
JSON المحدد (أسماء المحيط)
مساحات أسماء الترجمة لكل صفحة
ما هو هذا المقياس؟
الحجم الإجمالي المضغوط بتنسيق gzip لحزمة مكتبة التدويل. وهي تتضمن فقط المزود ومنطق استرداد المحتوى بعد تقليل الحجم (tree-shaking) والضغط (minification).
لماذا هو مهم؟
يقلل حجم المكتبة الأصغر من حمولة JavaScript الأولية، مما يؤدي إلى سرعة التنزيل وأوقات التنفيذ على العميل.
عرض كـ
افتح الجدول في نافذة منبثقة لعرض جميع محتويات البيانات بوضوح
| المكتبة | الاستراتيجية | حجم المكتبة (gz) | متوسط JS للصفحة (gz) | تسرب اللغة | تسرب الصفحة | متوسط المكون (gz) | تفاعلية E2E | الترطيب |
|---|---|---|---|---|---|---|---|---|
| base (بدون i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
next-intl | static | 14.7 KB | 153.6 KB | 4.2% | 89.8% | 21.8 KB | 16.0 ms | 14.7 ms |
next-intl | dynamic | 14.7 KB | 153.6 KB | 9.7% | 89.9% | 21.8 KB | 15.6 ms | 14.8 ms |
next-intl | scoped-static | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 80.1 KB | 17.9 ms | 17.4 ms |
next-intl | scoped-dynamic | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 22.9 KB | 17.8 ms | 16.8 ms |
next-intlayer | static | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 8.5 KB | 15.5 ms | 16.9 ms |
next-intlayer | dynamic | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 6.9 KB | 15.3 ms | 15.9 ms |
@intlayer/next-intl (توافق) | static | 8.0 KB | 147.5 KB | 0.0% | 0.0% | 8.1 KB | 14.5 ms | 12.8 ms |
@intlayer/next-intl (توافق) | dynamic | 8.0 KB | 148.7 KB | 0.0% | 0.0% | 8.1 KB | 11.7 ms | 12.8 ms |
كيف تقرأ هذه النتائج
- تكلفة وقت التشغيل. يزن التطبيق الأساسي 141.0 كيلوبايت لكل صفحة. ترفعه
next-intlإلى 153.6 كيلوبايت (+12.6 كيلوبايت gzip في كل صفحة)، بينما يرفعه Intlayer إلى 141.3 كيلوبايت فقط (+0.3 كيلوبايت). - التسريب. في الإعدادين الأكثر استخداماً (
staticوdynamic)، ترسلnext-intlما يقرب من ~90% من سلاسل الصفحات الأخرى في كل صفحة، لأن ملفen.jsonكاملاً يدخل في مزود العميل. يتطلب الوصول إلى 0% تقسيماً يدوياً دقيقاً. أما Intlayer فيحقق 0% تلقائياً. - حجم المكون. المكون الذي يستدعي
useTranslations()يُترجم في المتوسط إلى 21.8 كيلوبايت؛ والمكون نفسه معuseIntlayer()يبلغ 6.9 كيلوبايت فقط. وفي وضعscoped-staticتقفز مكوناتnext-intlإلى 80.1 كيلوبايت لأن كل مكون يُضمن مساحة أسمائه داخلياً.
الجدول الكامل، لكل مكتبة واستراتيجية، في تقرير قياس أداء Next.js.
النتائج على TanStack Start (use-intl)
تعتبر use-intl النواة المستقلة عن أي إطار عمل لمكتبة next-intl. نفس واجهة برمجة التطبيقات ونفس تنسيق الرسائل. مقارنتها مع intlayer على TanStack Start تزيل العوامل الخاصة بـ Next.js من المعادلة.
افتح الجدول في نافذة منبثقة لعرض جميع محتويات البيانات بوضوح
| المكتبة | الاستراتيجية | حجم المكتبة (gz) | متوسط JS للصفحة (gz) | تسرب اللغة | تسرب الصفحة | متوسط المكون (gz) | تفاعلية E2E |
|---|---|---|---|---|---|---|---|
| base (بدون i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms |
use-intl | static | 14.1 KB | 179.8 KB | 50.0% | 89.8% | 76.0 KB | 6.7 ms |
use-intl | dynamic | 14.1 KB | 119.4 KB | 0.0% | 89.8% | 75.9 KB | 7.0 ms |
use-intl | scoped-static | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 20.9 ms |
use-intl | scoped-dynamic | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 13.3 ms |
intlayer | static | 5.0 KB | 125.8 KB | 50.0% | 0.0% | 8.1 KB | 3.2 ms |
intlayer | dynamic | 5.0 KB | 118.6 KB | 0.0% | 0.0% | 6.3 KB | 3.6 ms |
@intlayer/use-intl (توافق) | dynamic | 7.3 KB | 129.7 KB | 0.0% | 0.0% | 9.3 KB | 8.7 ms |
كيف تقرأ هذه النتائج
- يرسل الإعداد البسيط لـ
use-intlما مقداره 68.8 كيلوبايت أكثر من JavaScript لكل صفحة مقارنة بالتطبيق الأساسي. - في وضع
dynamic، يصلuse-intlإلى 119.4 كيلوبايت، لكنه لا يزال يحمل تسرباً للصفحات بنسبة 89.8%. - يظهر الفارق المعماري بوضوح في حجم المكونات: 76-87 كيلوبايت مع
use-intlمقابل 6-8 كيلوبايت مع Intlayer. - تبديل اللغة أسرع بمرتين إلى أربع مرات مع Intlayer (3 مللي ثانية مقابل 7-21 مللي ثانية).
الجدول الكامل في تقرير قياس أداء TanStack Start.
لماذا هذا الفارق؟ الكتالوجات المركزية مقابل القواميس المجمعة

تتبع next-intl النموذج التقليدي: ملف JSON واحد لكل لغة، يُحمّل في getRequestConfig، ويُمرر إلى NextIntlClientProvider، ويُقرأ عبر t("namespace.key").
نسخ الكود إلى الحافظة
لا يمكن لوقت التشغيل معرفة المفاتيح التي ستستخدمها الصفحة فعلياً، لذا فإن الخيار الآمن هو إرسال الكتالوج بأكمله.
تزداد تكلفة عدم الوصول إلى هناك على محورين في وقت واحد، الصفحات واللغات:

بينما تقلب Intlayer هذه المسؤولية؛ حيث يتم الإعلان عن المحتوى بجانب المكون المعني مباشرة:
نسخ الكود إلى الحافظة
في وقت البناء، يرى المترجم أي مكون يستورد أي قاموس، ويحزم هذه القواميس فقط للغة النشطة، ويسقط أي محتوى غير مستخدم تلقائياً.
للحصول على أرقام صفdynamic، اضبطdictionary.importMode: 'dynamic'فيintlayer.config.ts. راجع دليل تحسين الحزمة.
تجربة المطور
مكون العميل (Client Component)
نسخ الكود إلى الحافظة
نسخ الكود إلى الحافظة
تذكر تضمين مساحة الأسماءcounterفي الرسائل الممررة إلىNextIntlClientProviderفي كل صفحة تعرض هذا المكون.
نسخ الكود إلى الحافظة
نسخ الكود إلى الحافظة
لا يوجد شيء لتسجيله في الصفحة: المكون يجلب محتواه الخاص معه.
مكونات الخادم المتزامنة (Server Components)
غالباً ما تكون عناصر واجهة المستخدم المشتركة (شريط التنقل، التذييل، البطاقات) مكونات خادم تُعرض كأبناء لمكونات العميل، لذا لا يمكن أن تكون غير متزامنة (async).
نسخ الكود إلى الحافظة
يتعين على الصفحة استدعاء await getTranslations("counter") و await getFormatter()، ثم تمرير النتائج كـ props. لم يعد المكون مستقلاً بذاته.
نسخ الكود إلى الحافظة
البيانات الوصفية (Metadata)
نسخ الكود إلى الحافظة
نسخ الكود إلى الحافظة
الاحتفاظ بـ API الخاص بـ next-intl مع مخرجات Intlayer
لا يتعين عليك إعادة كتابة مكوناتك للحصول على أرقام الأداء الموضحة أعلاه. حزمة @intlayer/next-intl هي محول متوافق مباشرة: يحتفظ بـ useTranslations وgetTranslations وuseFormatter وt.rich() وصيغ الجمع في ICU، ويقدمها من قواميس Intlayer التي يترجمها مترجم Intlayer.
نسخ الكود إلى الحافظة
في الاختبار، تحسن بناء التوافق لنفس التطبيق من 153.6 كيلوبايت إلى 147.5 كيلوبايت لكل صفحة، ومن 21.8 كيلوبايت إلى 8.1 كيلوبايت لكل مكون، ومن تسرب يقارب 90% إلى 0%، مع بقاء كود التطبيق دون أي تعديل. ويمكن لملفات messages/{locale}.json الحالية أن تظل مصدر الحقيقة عبر إضافة مزامنة JSON.
راجع دليل الانتقال من next-intl لاتباع الخطوات التفصيلية.
متى تختار أياً منهما؟
أنت تريد معيار النظام البيئي لـ Next.js، وتعتمد على ICU MessageFormat، وتطبيقك صغير إلى متوسط الحجم، أو تتكامل مع منصة ترجمة (Crowdin، Phrase، Lokalise...) تتوقع ملفات JSON مركزية. خصص وقتاً لتقسيم الكتالوجات إلى مساحات أسماء واختيار الرسائل باستخدام pick() لكل صفحة إذا كان الأداء مهماً.
تريد محتوى مخصصاً لكل مكون، وTypeScript صارماً، وأخطاء المفاتيح المفقودة في وقت البناء، وtree-shaking والتحميل الكسول دون أي جهد إضافي، ومكونات خادم متزامنة، وأدوات تحرير مدمجة (المحرر المرئي، نظام إدارة المحتوى CMS، الترجمة بالذكاء الاصطناعي، خادم MCP). ملائم بشكل خاص لقواعد الكود الكبيرة والمعيارية وأنظمة التصميم.
أنت تستخدم بالفعل next-intl وتريد الحصول على مزايا حجم الحزمة دون إعادة كتابة الكود. يحافظ محول التوافق على عمليات الاستيراد وملف messages/{locale}.json كمصدر وحيد للحقيقة. تم قياسه جنباً إلى جنب في next-intl مقابل @intlayer/next-intl.
الأسئلة الشائعة
ليس في وقت العرض (Render time). الفرق يكمن في ما يتم إرساله إلى المتصفح: يضيف next-intl +12.6 كيلوبايت gzip من وقت التشغيل على كل صفحة، وفي معظم الإعدادات الشائعة، يرسل ~90% من سلاسل الصفحات الأجنبية مع كل صفحة. تبديل اللغة وتفعيل الـ Hydration متقاربان على Next.js (15-18 مللي ثانية)؛ وعلى TanStack Start، يستغرق use-intl من 7 إلى 21 مللي ثانية مقارنة بـ 3-4 مللي ثانية لـ Intlayer.
نعم، باستخدام إعداد scoped-dynamic: قسّم messages/{locale}.json إلى مساحة أسماء لكل مسار، ثم استخدم pick(messages, [...]) في كل صفحة وحافظ على صحة هذا التعيين مع تنقل المكونات. هذا هو الجهد الذي تعكسه صفوف scoped-* في الاختبار. يصل Intlayer إلى 0% بدون ذلك لأن المترجم يحدد نطاق المحتوى لكل مكون. راجع تحسين الحزمة.
لا. يحافظ @intlayer/next-intl على useTranslations و getTranslations و useFormatter و t.rich() وصيغ الجمع في ICU ومساعدات التنقل، ويقدمها من قواميس مجمعة بواسطة مترجم Intlayer. سطر إضافي واحد في next.config.ts. دليلك خطوة بخطوة في دليل ترحيل next-intl.
دعم ICU الأصلي قيد التطوير في واجهة برمجة التطبيقات الأساسية. لكن محولات التوافق (@intlayer/next-intl، @intlayer/use-intl) تدعم ICU بالكامل: صيغ الجمع، و select، و selectordinal، و # و {ts, date, long} تتم معالجتها عبر محلل ICU في Intlayer. اقرأ تنسيق رسائل ICU لمزيد من التفاصيل.
نعم. يقرأها المكون الإضافي لمزامنة JSON، ويقسم المفاتيح العليا إلى قواميس، ويكتب الترجمات مرة أخرى في نفس الملفات عندما تقوم أداة CLI أو CMS بتحديثها. سير عمل المترجمين لديك لن يتغير.
مقارنات ذات صلة
نفس المقارنة المرجعية، مكتبات أخرى:
المزيد حول next-intl:
وثائق مرجعية:
لفهم أصل هذه المكتبات، اقرأ تاريخ i18n في JavaScript.
نجوم GitHub
تعد نجوم GitHub مؤشراً قوياً على شعبية المشروع وثقة المجتمع وأهميته على المدى الطويل.
نشاط الالتزامات (commits)
تعكس النجوم الشعبية، بينما تعكس الالتزامات حجم العمل المبذول في المشروع. عند كتابة هذا المقال، يضم Intlayer نحو 7,500 التزام، أي أكثر من معظم المكتبات المقارنة هنا، ونحو 5 أضعاف next-intl أو next-i18next.
- amannn/next-intl
- aymericzip/intlayer
الالتزامات على الفرع الافتراضي، المصدر: GitHub API.
Intlayer مستودع أحادي (monorepo)، لذا يشمل هذا العدد كل حزم أطر العمل وأداة CLI والتوثيق. اقرأ الالتزامات كمؤشر على النشاط، لا على الجودة.
تنزيلات npm
- next-intl
- next-intlayer
المصدر: واجهة تنزيلات سجل npm.
تكافئ أعداد التنزيل الحلول الأقدم، لا الأفضل. فالمكتبة التي صدرت قبل سنوات لا تزال تُثبَّت في كل مشروع اختارها آنذاك، وفي كل تشغيل لـ CI، وفي كل حزمة تعتمد عليها. هذا الرقم يقيس الجمود أكثر مما يقيس اختيارًا جديدًا.
تضخّم مساعدات الذكاء الاصطناعي هذا الأثر. فـ next-intl وi18next وvue-i18n منتشرة في الشيفرة التي تدربت عليها، لذا تقترحها افتراضيًا دون مقارنة البدائل. كل اقتراح يضيف تنزيلات، تغذي بدورها الاقتراح التالي. قارن بناءً على الاختبار المعياري لا على عدد التنزيلات.
الخاتمة
next-intl مكتبة قوية ومصانة جيداً، ويؤكد الاختبار أنها خيار جيد على Next.js. لكن نموذج الكتالوج المركزي يضع كل عبء التحسين على عاتق المطور: الإعداد البسيط يسرب نحو 90% من محتوى الصفحات الأخرى، ووقت التشغيل وحده يكلف +12.6 كيلوبايت gzip في كل صفحة.
ينقل Intlayer هذا العمل بأكمله إلى المترجم. القواميس لكل مكون، والتحميل الكسول لكل لغة، وتطهير المحتوى غير المستخدم تصبح جميعها مخرجات بناء تلقائية. والنتيجة على نفس التطبيق: +0.3 كيلوبايت لكل صفحة، 0% تسرب، ومكونات أصغر بـ 3 مرات، وتبديل لغة أسرع بمرتين إلى 4 مرات على TanStack Start.
جميع البيانات الأولية والتطبيقات وسيناريوهات الاختبار متاحة في مستودع Benchmark Bloom. يمكنك تشغيلها بنفسك.
راجع وثيقة 'لماذا Intlayer؟' لمزيد من التفاصيل.
التعليقات
لا توجد تعليقات بعد. كن أول من يشارك أفكاره.
