مقدمة: لماذا قد يكون TypeScript بطيئًا؟
TypeScript أداة قوية تضيف الكتابة الثابتة إلى JavaScript. ومع ذلك، غالبًا ما يواجه المطورون أن تطبيقات TypeScript تعمل بشكل أبطأ من JavaScript النقي "خارج الصندوق". الأسباب الرئيسية هي الترجمة الزائدة، والإعداد غير الصحيح للمترجم، وأنماط الكود غير المثلى. في هذه المقالة، سنستعرض طرق التحسين العملية التي ستساعد في تسريع عملية البناء ووقت تشغيل تطبيقك.
1. التنميط وإيجاد الاختناقات
قبل تحسين أي شيء، تحتاج إلى فهم ما الذي يسبب البطء. استخدم الأدوات المدمجة في المتصفح و Node.js.
1.1. أداء Chrome DevTools
سجل ملف تعريف تنفيذ التطبيق. انتبه إلى المهام الطويلة (Long Tasks) والاستدعاءات المتكررة لمجمع القمامة (GC). كود TypeScript بعد التجميع هو JavaScript عادي، لذا تعمل جميع طرق التنميط القياسية.
1.2. تحليل وقت البناء (tsc --generateTrace)
إذا كانت عملية التجميع نفسها بطيئة، استخدم العلم --generateTrace:
tsc --generateTrace trace_outputثم افتح الملف trace_output/trace.json في Chrome على العنوان chrome://tracing. سترى أي الملفات تستغرق وقتًا أطول في التجميع. غالبًا ما تكون هذه مكتبات كبيرة أو ملفات ذات استيرادات زائدة.
2. إعداد tsconfig.json للسرعة القصوى
التكوين غير الصحيح هو العدو الرئيسي للأداء. دعنا ننظر في الخيارات الرئيسية.
2.1. strict: true — لا تتعجل
وضع strict يشمل جميع الفحوصات الصارمة للأنواع. هذا يبطئ التجميع. لبناء الإنتاج، استخدم:
{ "compilerOptions": { "strict": false, "noImplicitAny": true, "strictNullChecks": true }}هذان الخياران يغطيان 90% من الأخطاء، لكنهما يعملان بشكل أسرع من strict الكامل.
2.2. خيارات لتسريع البناء
incremental: true— يفعل التجميع التزايدي. يحفظ TypeScript معلومات عن البناء السابق ويعيد تجميع الملفات المعدلة فقط.skipLibCheck: true— يعطل فحص الأنواع في ملفات التصريحات (.d.ts). هذا يعطي زيادة كبيرة في السرعة، خاصة عند استخدام العديد من المكتبات الخارجية.isolatedModules: true— يسمح باستخدام مترجمات أسرع (مثل esbuild) بدلاً من tsc.
مثال على تكوين محسّن للتطوير:
{ "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "node", "incremental": true, "skipLibCheck": true, "strict": false, "noImplicitAny": true, "strictNullChecks": true, "outDir": "./dist" }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.test.ts"]}3. تحسين وقت التشغيل: الأنواع وهياكل البيانات
أنواع TypeScript تختفي بعد التجميع، لكن "بصمتها" تبقى في شكل كود يولده المترجم.
3.1. تجنب الأنواع الشرطية المعقدة في وقت التشغيل
الأنواع الشرطية المعقدة (conditional types) قد تولد الكثير من الكود. بدلاً من ذلك، استخدم أنواع الاتحاد البسيطة:
// سيء: نوع شرطي معقدtype ResponseType<T> = T extends string ? { data: string } : { data: number };function handleResponse<T>(value: T): ResponseType<T> { ... }
// جيد: اتحاد بسيطtype ResponseType = { data: string } | { data: number };function handleResponse(value: string | number): ResponseType { ... }3.2. استخدم as const للثوابت
هذا يساعد TypeScript على استنتاج أنواع أكثر دقة، مما يقلل عدد الفحوصات:
const COLORS = ['red', 'green',