Vite Bundle Split: قلّل JavaScript الأولي بدون إعادة كتابة التطبيق
هتكسب تحميل أول أسرع لو فصلت الكود الثقيل في Vite بدل ما ترسله لكل المستخدمين من أول زيارة. في المثال ده هننزل JavaScript الأولي من 1.8MB إلى 620KB، مع trade-off واضح: أول فتح للصفحة الثقيلة هيحتاج request إضافي.
مستوى القارئ: متوسط
المشكلة باختصار
الطريقة الشائعة الغلط إنك تسيب كل imports في main.tsx أو في route رئيسي واحد. الطريقة دي بتفشل لما التطبيق يكبر: صفحة التقارير، محرر Markdown، مكتبة charts، وPDF viewer يدخلوا في نفس bundle حتى لو المستخدم فتح صفحة Dashboard بسيطة.
الافتراض إن عندك تطبيق React أو Vue مبني بـ Vite، وفيه route ثقيل لا يفتحه كل المستخدمين. مثال واقعي: SaaS داخلي عنده 40 ألف زيارة يوميًا، لكن صفحة التقارير المتقدمة لا يفتحها إلا 12% من المستخدمين. إرسال مكتبة charts لكل الناس هنا تكلفة واضحة.
مثال بسيط قبل الشرح الدقيق
ركز في المثال ده: عندك مكتب استقبال. مش منطقي تحط كل ملفات المحاسبة، المخزن، والعقود على مكتب الموظف اللي هيسأل عن اسم العميل فقط. الأفضل إن ملف المحاسبة يطلع من الأرشيف لما الموظف يحتاجه.
في الواجهة نفس الفكرة بالظبط. الصفحة الأساسية تحتاج shell خفيف: navigation، auth state، وجدول بسيط. أما editor أو charting engine فده ملف منفصل يتم تحميله لما route يتفتح. علميًا، ده اسمه code splitting: تقسيم كود التطبيق إلى chunks أصغر، بحيث المتصفح يحمّل الجزء المطلوب أولًا ويؤجل الباقي.
الخطوة الأولى: افصل route ثقيل بـ dynamic import
ابدأ بأعلى route في الحجم. لا تبدأ بتقسيم 20 component صغير. أفضل طريقة إنك تفتح bundle analyzer أو تقيس ملفات dist/assets، ثم تختار route واضح مثل /reports.
// src/router.tsx
import { lazy, Suspense } from 'react';
import Dashboard from './pages/Dashboard';
const ReportsPage = lazy(() => import('./pages/ReportsPage'));
export function AppRoutes() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/reports" element={<ReportsPage />} />
</Routes>
</Suspense>
);
}
الـ trade-off هنا إن أول دخول إلى /reports هيطلب chunk إضافي. المكسب إن المستخدم الذي لا يفتح التقارير لن يدفع تكلفة chart editor من البداية. لو عندك route يفتحه أقل من 30% من المستخدمين، غالبًا المكسب يستاهل.
الخطوة الثانية: امنع vendor chunk من التحول لصندوق واحد ضخم
بعد dynamic import، ممكن تلاقي vendor.js لسه كبير. السبب إن المكتبات كلها اتجمعت في chunk واحد. استخدم بحذر لفصل المكتبات الثقيلة ذات الاستخدام المحدد.