المؤلف:
    إنشاء:2026-09-13آخر تحديث:2026-09-13

    Lingui مقابل @intlayer/lingui | نفس وحدات الماكرو، بيئة تشغيل مختلفة

    حزمة @intlayer/lingui هي محول توافق (compat adapter) لمكتبتي @lingui/core و @lingui/react. استدعاءاتك لكل من t`...` و <Trans> و useLingui() و i18n._() تبقى كما هي تماما؛ تواصل وحدات الماكرو التصريف دون تغيير؛ والشيء الوحيد الذي يتغير هو مصدر النصوص في وقت التشغيل (runtime). بدلا من وجود فهرس مجمع واحد لكل لغة، يرتبط كل موقع استدعاء بقاموس Intlayer تم تجميعه خصيصا له.

    تقيس هذه المقالة هذا التحول على نفس تطبيق TanStack Start، مبنيا مرة باستخدام Lingui الصافي ومرة باستخدام المحول. الأرقام مأخوذة من Benchmark Bloom. للمقارنة بين المكتبتين كمكتبتين مستقلتين، اقرأ Lingui مقابل Intlayer. تركز هذه المقالة على ما يغيره المحول، وأين لا يقدم فائدة إضافية.

    خلاصة سريعة (tl;dr): في نفس تطبيق TanStack Start، قلص @intlayer/lingui متوسط حجم المكون من 85.5 كيلوبايت إلى 12.8 كيلوبايت بتنسيق gzip، وخفض وقت الترطيب (hydration) من 28 مللي ثانية إلى 19.7 مللي ثانية، وسرع التبديل بين اللغات من 5.9 مللي ثانية إلى 2.9 مللي ثانية، مع بقاء وحدات الماكرو كما هي دون تعديل. في الإعداد البسيط (تحميل كافة الفهارس مسبقا)، أزال أيضا 90% من تسرب الصفحات ووفر 12 كيلوبايت لكل صفحة. ولكن في إعداد التحميل الكسول (lazy-loaded)، يرسل المحول 137 كيلوبايت لكل صفحة مقابل 115 كيلوبايت لمكتبة Lingui العادية: يرجع ذلك إلى أن المحول يحلل صياغة ICU في وقت التشغيل بينما توفر Lingui مصفوفات رموز مجمعة مسبقا. تسرب اللغة المصدر (~9-10%) متطابق في الجانبين، لأنه ينبع من النص الاحتياطي message المضمن داخل المكونات وليس من بيئة التشغيل. المحول عبارة عن إضافة Vite؛ وتمت القياسات على TanStack Start.

    ما هو @intlayer/lingui

    تتكون Lingui من مصرف وبيئة تشغيل. يتم استخراج وحدات الماكرو في الكود المصدري إلى فهرس بصيغة .po (أو JSON) لكل لغة، ثم تترجم إلى وحدة JS لكل لغة، ويتم تحميلها في نسخة I18n عامة عبر i18n.load() + i18n.activate(). يشترك كل استدعاء useLingui() في تلك النسخة؛ ويبحث كل استدعاء _() عن معرفه في الفهرس النشط.

    يحافظ @intlayer/lingui على وحدات الماكرو وواجهة برمجة التطبيقات ويستبدل آلية البحث في الفهارس:

    1. الأسماء المستعارة للاستيراد (Import aliasing). تغلف إضافة lingui() من @intlayer/lingui/plugin إضافة vite-intlayer وتضيف مدخلات resolve.alias بحيث يتم توجيه @lingui/core و @lingui/react إلى @intlayer/lingui. استيراداتك الحالية لا تتغير إطلاقا.
    2. الفهارس كمصدر وحيد للحقيقة. تقرأ إضافة syncJSON (أو syncPO لملفات .po) فهارسك الحالية وتحولها إلى قواميس Intlayer، مع إعادة كتابة الترجمات عند تحديثها بواسطة أداة CLI أو نظام إدارة المحتوى CMS. مع خيار splitKeys: "key-prefix"، يتحول الفهرس المسطح ذو المعرفات المنقطة (footer.github, hero.title) إلى قواميس صغيرة مقسمة حسب البادئة بدلا من ملف واحد ضخم بحجم 244 كيلوبايت.
    3. الربط حسب موقع الاستدعاء. يجمع مسار التحسين في Intlayer المعرفات الممررة إلى _ و t و <Trans> في كل ملف، ويسلم القواميس المطابقة فقط إلى المكون. يرتبط <Trans id="hero.title"> بشكل مستقل؛ بينما يرتبط useLingui() بجميع البادئات المستخدمة في الملف. المعرفات التي لا تحتوي على نقاط (المعرفات المجزأة، mockBanner) ترجع تلقائيا إلى قاموس messages الاحتياطي الفردي في Lingui.
    src/components/Hero.tsx
    // الكود الخاص بك دون أي تعديل
    import { useLingui } from "@lingui/react";
    import { Trans } from "@lingui/react/macro";
    
    const Hero = () => {
      const { _ } = useLingui();
      return (
        <section>
          <h1>{_({ id: "hero.title", message: "Measure what you ship" })}</h1>
          <Trans id="hero.subtitle">Every byte counts</Trans>
        </section>
      );
    };
    
    ما يصدره المصرف (مبسط)
    import _dicHash_hero from "../.intlayer/dictionaries/hero.mjs";
    import {
      useDictionary as useLingui,
      TransDictionary as Trans,
    } from "@intlayer/lingui";
    
    const Hero = () => {
      const { _ } = useLingui(_dicHash_hero);
      return (
        <section>
          <h1>{_({ id: "hero.title", message: "Measure what you ship" })}</h1>
          <Trans id="hero.subtitle" dictionary={_dicHash_hero}>
            Every byte counts
          </Trans>
        </section>
      );
    };
    

    لم يعد المكون بحاجة للوصول إلى النسخة العامة والفهرس المتجانس خلفها. بل يتعامل مباشرة مع hero. وهذا هو التفسير الرئيسي لانخفاض حجم المكونات بمقدار 7 أضعاف في الجدول أدناه.

    ما يحتفظ به المحول، وما يتجاهله، وما لا يستبدله

    واجهة برمجة تطبيقات Linguiمع @intlayer/lingui
    وحدات ماكرو t`...` و msg و plural و select و <Trans>✅ محتفظ بها. احتفظ بإضافة @lingui/babel-plugin-lingui-macro أو @lingui/swc-plugin قبل معالجة Intlayer
    useLingui(){ i18n, _, t }✅ محتفظ بها. تعمل خارج الـ Provider أيضا (تستنتج اللغة من react-intlayer)
    i18n._(id, values) و i18n.t()✅ محتفظ بها. تحل المعرفات الصريحة والمجزأة على حد سواء
    صيغ الجمع في ICU و select و selectordinal و #✅ محتفظ بها، من خلال محلل ICU المدمج في Intlayer
    i18n.date() و i18n.number() و formats✅ محتفظ بها، مدعومة بمحرك Intl الأصلي
    I18nProvider✅ محتفظ بها. تغلف IntlayerProvider وتستمع إلى i18n.on("change") لإعادة التصيير مع activate()
    i18n.activate(locale)✅ محتفظ بها
    i18n.load(locale, messages) / loadAndActivate()⚠️ مقبولة كـ حل احتياطي لوقت التشغيل. القواميس المجمعة لها الأولوية؛ يظهر تحذير للمطور باقتراح إزالة الكود
    setupI18n({ messages, missing })⚠️ يتم دمج messages كحل احتياطي؛ ويتم تجاهل missing
    lingui extract / lingui compile✅ يظل سير عملك المعتاد كما هو. وجه syncPO / syncJSON إلى الفهارس المستخرجة
    defaultComponent على I18nProvider⚠️ يتم تخزينه في السياق ولكن لا يطبق أثناء التصيير
    Next.js❌ تغلف الإضافة vite-intlayer. تدعم فقط Vite و TanStack Start و React Router

    اختبار الأداء المقارن (Benchmark)

    ما تم قياسه

    تبني مجموعة اختبارات Benchmark Bloom نفس التطبيق في كل إعداد: 10 صفحات (home, about, blog, careers, contact, FAQ, pricing, products, settings, team)، و 10 لغات (en, fr, es, de, it, pt, zh, ja, ko, ru)، ومكونات ومحتوى متطابق تماما. قيس أداء الصفحات باللغتين en و fr.

    تم بناء Lingui بأربع استراتيجيات تحميل: بدءا من الاستيراد المسبق لجميع الفهارس المجمعة (static) وصولا إلى استيراد الفهرس حسب المسار بنمط كسول (scoped-dynamic). بينما تم بناء المحول على نفس المكونات تماما، مع تعديل ملفي vite.config.ts و intlayer.config.ts فقط. يجمع صف static كافة اللغات؛ بينما يحمل صف dynamic (importMode: 'dynamic') اللغة النشطة عند الطلب. لا يوجد نمط "scoped" لأن مسار التحسين يضبط النطاق لكل موقع استدعاء بشكل تلقائي.

    لكل بناء، يسجل الاختبار المعايير التالية:

    • حجم المكتبة (Lib size): حجم gzip لمكون فارغ يستورد مكتبة التدويل فقط.
    • حجم JS لكل صفحة (Page JS): متوسط حجم JavaScript المحمل بتنسيق gzip لكل صفحة عبر كافة الصفحات واللغات.
    • نسبة تسرب اللغة (Locale leak %): نسبة السلاسل المترجمة المحملة في ملف JS التابعة للغات لا يعرضها المستخدم حاليا.
    • نسبة تسرب الصفحة (Page leak %): نسبة السلاسل المترجمة المحملة في ملف JS التابعة لصفحات لا يتواجد فيها المستخدم حاليا.
    • متوسط حجم المكون (Component avg): متوسط حجم gzip لكل مكون عند تجميعه بشكل مستقل.
    • سرعة الاستجابة الفعلية (E2E reactivity): الوقت الفعلي المستغرق بين اختيار لغة جديدة وتحديث علامة html[lang] في الـ DOM (عبر Playwright، متوسط 5 تكرارات).
    • الترطيب (Hydration): مدة مرحلة ترطيب React.
    الأرقام أدناه مأخوذة من التشغيل بتاريخ 2026-09-12 باستخدام @lingui/react بالإصدار 6.6.0 و @intlayer/lingui بالإصدار 9.5.1. التطبيق التجريبي مصمم بحجم صغير عمدا (بضع عشرات من النصوص لكل لغة)، لذا تصف نسب التسرب نمطا هيكليا: يتزايد التسرب طرديا مع تضخم المحتوى بينما تظل تكلفة بيئة التشغيل ثابتة.

    النتائج على TanStack Start

    الإعدادالاستراتيجيةحجم المكتبة (gz)متوسط JS للصفحة (gz)تسرب اللغةتسرب الصفحاتمتوسط المكون (gz)استجابة E2Eالترطيب
    الأساس (بدون i18n)-0.0 ك.ب111.0 ك.ب0.0%0.0%0.7 ك.ب8.1 م.ث21.6 م.ث
    Linguistatic11.2 ك.ب152.2 ك.ب50.0%90.0%58.0 ك.ب3.9 م.ث19.9 م.ث
    Linguidynamic11.2 ك.ب115.2 ك.ب9.3%0.0%85.5 ك.ب5.9 م.ث28.0 م.ث
    Linguiscoped-static11.2 ك.ب120.8 ك.ب4.0%0.0%147.9 ك.ب7.1 م.ث33.9 م.ث
    Linguiscoped-dynamic11.2 ك.ب120.2 ك.ب8.6%0.0%83.7 ك.ب42.1 م.ث32.9 م.ث
    @intlayer/linguistatic10.3 ك.ب140.5 ك.ب50.0%0.0%14.9 ك.ب3.3 م.ث11.3 م.ث
    @intlayer/linguidynamic10.3 ك.ب137.0 ك.ب9.9%0.0%12.8 ك.ب2.9 م.ث19.7 م.ث
    intlayer (النسخة الأصلية)static5.0 ك.ب125.8 ك.ب50.0%0.0%8.1 ك.ب3.2 م.ث11.5 م.ث
    intlayer (النسخة الأصلية)dynamic5.0 ك.ب118.6 ك.ب0.0%0.0%6.3 ك.ب3.6 م.ث14.1 م.ث

    كيف تقرأ هذه النتائج

    • المكونات: أصغر بـ 7 أضعاف. هذا هو الأثر الجوهري للمحول. يبلغ متوسط حجم مكون Lingui المترجم بشكل معزول 58-148 كيلوبايت تبعا للاستراتيجية، لأن useLingui() يرتبط بالنسخة العامة وبكافة الفهارس المحملة بداخلها. بينما يبلغ متوسط نفس المكون مع المحول 12.8-14.9 كيلوبايت: فهو لا يستورد سوى قواميسه ومحلل ICU المخصص له فقط.
    • الترطيب: أسرع بمقدار 8-14 مللي ثانية. يتم تشغيل i18n.load() + i18n.activate() في جهة العميل قبل أن يتمكن React من بدء الترطيب؛ وكلما زاد التحميل الكسول في Lingui، طالت هذه المدة (28-34 مللي ثانية). مع المحول، تصل القواميس كاستيرادات ثابتة عادية وضعها المجمع بالفعل داخل حزمة الصفحة: 11.3 مللي ثانية في النمط static، و 19.7 مللي ثانية في النمط dynamic.
    • التبديل بين اللغات: أسرع بضعفين وبدون تأخير مفاجئ. يستغرق إعداد Lingui المحسن scoped-dynamic حوالي 42 مللي ثانية لتحديث html[lang]، لأن فهرس المسار يحتاج إلى جلب وتحميل وتفعيل قبل ظهور التغيير. بينما يستقر المحول عند 2.9-3.3 مللي ثانية في كلا الوضعين.
    • إصلاح الإعداد البسيط تلقائيا. ترسل Lingui الثابتة كافة الفهارس في كل صفحة: 152.2 كيلوبايت، و 90% تسرب للصفحات. أما المحول الثابت: 140.5 كيلوبايت، و 0% تسرب للصفحات، لنفس المكونات تماما.
    • حجم البيانات لكل صفحة: Lingui تتفوق في نمط dynamic بمقدار 22 كيلوبايت. هذا رقم يجب التعامل معه بواقعية. تترجم Lingui الرسائل إلى مصفوفات رموز مسبقة أثناء البناء وترسل بيئة تشغيل خفيفة بحجم 11 كيلوبايت تمر عليها فقط. بينما يرسل المحول محلل ICU الخاص بـ Intlayer (حوالي 15 كيلوبايت إضافية من @intlayer/core مقارنة بالبناء الأصلي)، وطبقة المحول (~10 كيلوبايت) و react-intlayer (~6 كيلوبايت). في هذا التطبيق، ينتج عن ذلك 137.0 كيلوبايت مقابل 115.2 كيلوبايت. إذا كان خفض حجم الصفحة هو هدفك الوحيد وكنت تستخدم بالفعل Lingui المحمل كسولا، فلن يساعدك المحول في هذا المعيار.
    • تسرب اللغة المصدر متطابق في الطرفين. 9.3% في Lingui و 9.9% في المحول بنمط dynamic. يعود ذلك إلى المكونات نفسها: إذ يحمل الاستدعاء i18n._({ id: "careers-benefits.pay", message: "Top-of-market compensation" }) النص الإنجليزي الأصلي كاحتياط، وكذلك الأمر مع مخرجات الماكرو ما لم يحذف حقل message. ويهبط هذا النص الإنجليزي في حزمة اللغة الفرنسية fr بغض النظر عن بيئة التشغيل المستخدمة. أما مكتبة intlayer الأصلية (.content.ts، بدون نص احتياطي مدمج في الكود) فتحقق 0% تماما.

    لماذا تتغير الأرقام، ولماذا يظل أحدها ثابتا

    يتحكم عاملان رئيسيان في هذه النتائج: ما يرتبط به المكون، و الصيغة التي تنتقل بها الرسائل.

    الارتباط (Binding). في Lingui، وحدة القياس والتجزئة هي اللغة بالكامل. يمثل ملف messages.mjs الخاص باللغة الفرنسية fr وحدة واحدة مدمجة؛ وأي مكون يستورد النسخة التي حملته يحصل على إمكانية الوصول إلى المحتوى كاملا، مما يعيق أداة التجميع عن التقسيم لمستوى أدق. مع المحول، تكون الوحدة هي موقع الاستدعاء نفسه: أصبحت أجزاء hero و footer استيرادات منفصلة، يتم تجزئتها وتحميلها عند الحاجة لكل مكون. وهذا هو السر وراء تقليص حجم المكونات وتحسين الترطيب والتخلص من تسرب الصفحات.

    bash
    .
    ├── lingui.config.ts
    └── src
        ├── i18n.ts                          # setupI18n(), load(), activate()
        ├── locales
       ├── en/messages.mjs              # مخرجات lingui compile، واحد لكل لغة
       └── fr/messages.mjs
        └── components
            └── Hero.tsx                     # useLingui(); _("hero.title")
    
    bash
    .
    ├── intlayer.config.ts                   # syncJSON({ splitKeys: "key-prefix" })
    ├── .intlayer/                           # منشأ تلقائيا: قاموس لكل بادئة معرف، لكل لغة
    └── src
        ├── locales
       ├── en/messages.json             # دون تغيير، يظل المصدر الوحيد للحقيقة
       └── fr/messages.json
        └── components
            └── Hero.tsx                     # useLingui(); _("hero.title")  ← دون تغيير
    

    صيغة الرسائل (Format). تحول مرحلة التصريف في Lingui التعبير {count, plural, one {# item} other {# items}} إلى مصفوفة رموز مجمعة مسبقا، وبالتالي لا تحتاج بيئة التشغيل لتحليل صياغة ICU أبدا. بينما يحتفظ المحول بالنص كنص مجرد ويحلله عبر محلل ICU المدمج في Intlayer. هذا استهلاك ثابت يبلغ حوالي 15 كيلوبايت تدفعه مرة واحدة في الصفحة، وهو السبب وراء تأخر صف dynamic في عدد البايتات مع تفوقه في كل المعايير الأخرى. تتفادى نسخة Intlayer الأصلية ذلك لأن قواميس .content.ts تعتمد على عقد enu() / insert() التي يحلها المصرف مسبقا في مرحلة البناء.

    الترقية في ثلاث خطوات

    1. التثبيت

      bash
      npx intlayer init --interactive
      

      يكتشف الأمر بيئة Lingui تلقائيا، ويقرأ lingui.config.ts لاختيار syncPO (لفهارس .po) أو syncJSON (لفهارس JSON)، ويثبت intlayer و react-intlayer و @intlayer/lingui وإضافة المزامنة المطابقة، كما يستبدل @lingui/vite-plugin بإضافة المحول في vite.config.ts. احتفظ بالحزم @lingui/core و @lingui/react وإضافة الماكرو مثبتة: حيث تستمر وحدات الماكرو في العمل ويعتمد المحول على أنواع Lingui البرمجية.

    2. ربط Intlayer بفهارسك الحالية

      لفهارس JSON (عند وجود format: "minimal" في lingui.config.ts):

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      import { syncJSON } from "@intlayer/sync-json-plugin";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
          defaultLocale: Locales.ENGLISH,
        },
        dictionary: {
          importMode: "dynamic",
          format: "icu",
        },
        plugins: [
          syncJSON({
            format: "icu",
            source: ({ locale, key }) => `./src/locales/${locale}/${key}.json`,
            // تجميع المعرفات المنقطة حسب أول مقطع: `footer.github` ← قاموس `footer`
            splitKeys: "key-prefix",
          }),
        ],
      };
      
      export default config;
      

      لفهارس .po، استبدل syncJSON بـ syncPO من حزمة @intlayer/sync-po-plugin واستخدم نفس نمط source مع امتداد .po. راجع توثيق إضافة Sync PO.

      خيار splitKeys: "key-prefix" هو المفتاح الفعلي لتقليص أحجام المكونات. يحافظ ملف الفهرس على بنيته المسطحة؛ والتقسيم يظهر فقط في القواميس المنشأة، وتقوم المزامنة العكسية بإعادة دمج المفاتيح بسلاسة.

    3. إضافة الملحق البرمجي

      vite.config.ts
      import { defineConfig } from "vite";
      import { tanstackStart } from "@tanstack/react-start/plugin/vite";
      import viteReact from "@vitejs/plugin-react";
      import { lingui } from "@intlayer/lingui/plugin";
      
      export default defineConfig({
        plugins: [
          tanstackStart(),
          viteReact({
            // احتفظ بإضافة الماكرو؛ يجب تشغيلها قبل معالجة Intlayer
            babel: { plugins: ["@lingui/babel-plugin-lingui-macro"] },
          }),
          lingui(),
        ],
      });
      

      تغلف إضافة lingui() حزمة vite-intlayer (مراقبة المحتوى، وتجميع القواميس، ومسار التحسين) وتوجه @lingui/core و @lingui/react نحو المحول عبر الأسماء المستعارة. نفذ البناء، وستحصل فورا على نفس النتائج الموضحة أعلاه.

    ما يمكنك حذفه بعد الانتهاء

    الملف / النمطالسبب
    await import(`./locales/${locale}/messages.mjs`) | يتم استيراد القواميس مباشرة بواسطة المكونات المستفيدة. يتحول i18n.load() إلى خيار احتياطي
    i18n.load() / i18n.loadAndActivate()احتفظ بـ i18n.activate(locale)؛ وتخلص من تحميل الفهارس يدويا
    أمر lingui compile في سكربتات البناءفقط في حال اعتمدت على JSON أو .po كمصدر ولم تعد تستورد وحدات برمجية مجمعة

    ما تكسبه بخلاف تقليص الأحجام

    • اكتشاف الترجمات المفقودة. يوقف أمر npx intlayer test مسارات CI عند غياب معرف في لغة ما؛ بينما يكتفي lingui extract بعرض إحصائيات تقريبية.
    • الملء التلقائي عبر npx intlayer fill لترجمة المفاتيح الناقصة باستخدام موفر الذكاء الاصطناعي الذي تفضله (OpenAI, Anthropic, Mistral, Gemini...) وإعادة حفظها مباشرة في فهارسك.
    • المحرر المرئي ونظام إدارة المحتوى CMS يتعاملان مع نفس القواميس، مما يسمح للفريق غير التقني بتعديل ملفات .po و JSON عبر واجهة تفاعلية.
    • الانتقال التدريجي نحو .content.ts. يمكنك في أي وقت ترقية مكون بعينه من useLingui() إلى useIntlayer("hero") مع ملف محتوى مجاور له. كلا النوعين من القواميس يتعايشان ويندمجان بسلاسة.

    قيود يجب معرفتها قبل البدء

    • التكلفة الإضافية لكل صفحة في نمط dynamic. كما وضحنا أعلاه: توقع زيادة قدرها نحو 20 كيلوبايت لكل صفحة مقارنة بإعداد Lingui المحمل كسولا في التطبيقات الصغيرة. هذا الفارق لا يزداد بزيادة المحتوى (لأنه يعود للمحلل وليس الفهارس)، ولكنه لا يتقلص أيضا.
    • بقاء تسرب اللغة المصدر. تشتمل واصفات الرسائل ونواتج الماكرو على النص الإنجليزي كاحتياط. إذا كان هذا الأمر يشكل أولوية لك، فالحل هو تنظيف حقل message أو نقل المكون إلى .content.ts، وليس المحول بحد ذاته.
    • دالة i18n.load() باتت احتياطية. إذا واصلت استيراد الفهارس المجمعة واستدعاء load()، فسينتهي بك الأمر بتحميل الحزمة القديمة والجديدة معا. احرص على حذف تلك الاستيرادات.
    • حصري لـ Vite. لا يوجد ملحق لـ Next.js ضمن @intlayer/lingui. مشاريع Next.js المعتمدة على Lingui يفضل أن تتوجه مباشرة إلى next-intlayer.
    • عدم تطبيق defaultComponent. إذا كنت تعتمد عليه لتغليف كل عنصر <Trans> تلقائيا، أضف التغليف بشكل صريح داخل المكونات.

    متى تستخدم كل خيار؟

    • ابق مع Lingui إذا كنت تطبق بالفعل بنية scoped-dynamic، ومعيارك الحاسم الوحيد هو الحجم الأدنى للبايتات لكل صفحة، وكان زمن 42 مللي ثانية لتبديل اللغة و 30 مللي ثانية للترطيب مقبولا في تطبيقك.
    • استخدم @intlayer/lingui إذا كنت تستخدم Lingui وتريد مكونات أخف وزنا، وترطيبا وتبديلا أسرع للغات، و 0% تسرب للصفحات في الإعداد البسيط، ومعرفات محددة النوع، وفحوصات CI وترجمة مدعومة بالذكاء الاصطناعي دون الحاجة لتعديل الماكرو. إنه الجسر المثالي لتطوير مشاريع Lingui الحالية.
    • انتقل إلى Intlayer الأصلية (react-intlayer) عندما تبدأ إعادة هيكلة المكونات. إنها الحل الوحيد في جدول المقارنة الذي يحقق 0% تسرب للغة، وبيئة تشغيل بحجم 5 كيلوبايت وزيادة طفيفة لا تتعدى +7.6 كيلوبايت لكل صفحة مقارنة بالتطبيق الأساسي.

    مقارنات ذات صلة

    الخاتمة

    يغير @intlayer/lingui جهة الارتباط لمواقع استدعاء Lingui: فبدلا من الارتباط بالنسخة العامة وفهرس اللغة الضخم، يرتبط كل مكون بقاموس مخصص تم تصريفه له على حدة. في نفس تطبيق TanStack Start يحقق ذلك مكونات أصغر بـ 7 أضعاف، و ترطيبا أسرع بـ 8-14 مللي ثانية، و تبديلا أسرع للغات بضعفين مع تفادي التعليق المؤقت البالغ 42 مللي ثانية، دون تحرير أي ماكرو. وهو لا يغير النصوص الاحتياطية المضمنة في المكونات (مما يبقي على تسرب لغة المصدر)، كما يحلل صيغة ICU في وقت التشغيل (مما يضيف نحو 20 كيلوبايت لكل صفحة في الوضع الديناميكي مقارنة بـ Lingui الصافية). حدد أولويات الأداء في مشروعك قبل حسم قرارك.

    تتوفر جميع البيانات التفصيلية وتطبيقات الاختبار وسكربتات القياس في مستودع Benchmark Bloom. ندعوك لتجربتها بنفسك.

    راجع توثيق 'لماذا Intlayer؟' لمزيد من التفاصيل.

    التعليقات

    لا توجد تعليقات بعد. كن أول من يشارك أفكاره.

    مقالات ذات صلة

    آخر المقالات