حلّت إضافة next-intl (انظر المقال
السابق) مشكلة توجيه اللغات. كما
أضافت تبعية على محلّل رسائل ICU الخاص بـ@formatjs، والذي يعمل افتراضيًا
داخل المتصفح — يقوم متصفح كل زائر بتحميل وتشغيل الآلية التي تُحلّل صياغة
رسائل من نوع {minutes, plural, one {...} other {...}}، رغم أن كل رسالة
حقيقية يقدّمها هذا الموقع معروفة وقت البناء ولا تتغيّر أبدًا حسب الطلب.
القياس قبل الافتراض
بدلًا من تخمين التكلفة، استخدمت محلّل الحزم (bundle analyzer) المدمج في
Next.js 16.1+ والمخصّص لـTurbopack (npx next experimental-analyze)
للحصول على خريطة وحدات حقيقية. كشفت عن كتلة @formatjs/ مخصّصة بحجم
22.88 كيلوبايت في أعلى حزمة العميل — ليس خطأ تقريب، وليس أمرًا كانت
تدقيقات Lighthouse (bootup-time/mainthread-work-breakdown، وكلاهما
بنتيجة 0 في كل اختبار لهذا الموقع حتى الآن) لتشرحه وحدها دون فتح خريطة
الوحدات مباشرة.
Note
استخدمت في البداية @next/bundle-analyzer بدافع العادة، كونه الأداة
الأكثر ذكرًا. أبلغ البناء فورًا أنه غير متوافق مع بنيات Turbopack — قيد
حقيقي وموثّق، لا خطأ إعداد من جانبي. أزلته وانتقلت إلى المحلّل المدمج في
Next بدلًا من الالتفاف حول عدم التوافق.
الحل
توفّر next-intl خيار experimental.messages.precompile الذي ينقل تحليل
ICU إلى وقت البناء بدلًا من العميل. تُجمَّع قواميس الرسائل في صيغة يمكن
لوقت التشغيل استهلاكها مباشرة، دون الحاجة لأي محلّل داخل المتصفح على
الإطلاق.
const withNextIntl = createNextIntlPlugin({
requestConfig: "./i18n/request.ts",
experimental: {
messages: {
path: "./messages",
format: "json",
locales: "infer",
precompile: true,
},
},
});
أدى تفعيل هذا الخيار فورًا إلى خطأ TypeScript حقيقي — نوع (type) الإصدار
المثبَّت لـexperimental.messages يتطلّب حقل locales الذي يحذفه المثال
المبسّط في التوثيق الرسمي لهذا الخيار تحديدًا. إضافة locales: "infer"
(اكتشاف تلقائي من مجلد messages/) أصلح المشكلة.
التحقق من المكسب الفعلي
Decision
لم أعتبر وجود الميزة دليلًا على أنها تعمل — أعدت تشغيل محلّل الحزم قبل وبعد، وقارنت الأرقام الفعلية، بنفس الانضباط المتّبع في تحقيق Lighthouse في المقال أعلاه.
انخفض إجمالي "All Route Modules" من 386.56 كيلوبايت إلى 359.76 كيلوبايت
مضغوطة — أي توفير قدره 26.8 كيلوبايت، مطابق تقريبًا لكتلة
@formatjs/ المحدَّدة سابقًا (والتي اختفت الآن تمامًا من خريطة الوحدات،
باستثناء بقايا هامشية). انخفض عدد الوحدات من 227 إلى 224. بقي npm run build وnpm test نظيفَين بعد ذلك — 24 من 24 صفحة، ومجموعة الاختبارات
كاملة ناجحة.
ما كنت سأفعله بشكل مختلف
لا شيء في التسلسل — القياس، ثم صياغة فرضية حول السبب، ثم تطبيق إصلاح مستهدف،
ثم إعادة القياس للتأكد من المكسب الفعلي بدلًا من الثقة بوصف الميزة. الشيء
الوحيد الذي سأغيّره مستقبلًا: التحقق من كامل سطح النوع (type) لأي خيار إعداد
مقابل الإصدار المثبَّت قبل كتابة المثال المبسّط من التوثيق، فهذه المرة
الثانية في اليوم نفسه التي توقعني فيها هذه الفجوة (انظر حادثة hasLocale
في المقال السابق).