تقسيم الكود (Code Splitting)
الدرس 28 من 34 · دورة TanStack Router الكاملة · 7 دقيقة و50 ثانية
الفيديو الأصلي باللغة الإنجليزية. إذا تعذّر تشغيله هنا، شاهده على موقع المؤلف. التفريغ النصي العربي الكامل أدناه.
مستودع الكود لهذا الدرس
الفرع:
code-splitting
[00:01] عن تقسيم الكود (code splitting) والتحميل المسبق (preloading) في TanStack Router. فلنبدأ بتقسيم الكود في TanStack Router. فتقسيم الكود، كما قد تعلم، تقنية لتحسين حجم الحزمة (bundle) وأداء التحميل في
[00:13] تطبيقك. فبالاعتماد على تقسيم الكود يمكننا تقليل مقدار الكود الذي نحتاج إلى تحميله بدايةً عند التحميل الأوّل لتطبيقنا، بحيث يمكن لتطبيقنا أن يتحمّل بسرعة أكبر، ثم لاحقًا عندما نطلب مساراتٍ معيّنة في
[00:26] تطبيقنا يمكننا تحميل مزيدٍ من أجزاء الكود (chunks) عند الطلب. فـ TanStack Router يفصل الكود إلى فئتين.
[00:34] تهيئة مسارٍ حادّة (critical route configuration) وتهيئة مسارٍ غير حادّة. فـ تهيئة المسار الحادّة هي الكود الذي يلزم لتصيير المسار الحالي (render) وبدء عملية تحميل البيانات في أقرب وقت ممكن. فمثلًا
[00:47] عند تعريف مسارٍ لَدَينا تعريف المسار، ولَدَينا التحقّق من صحة معامِلات البحث (search parameters)، ولَدَينا سياق دالة المُحمِّل (loader) وما إلى ذلك. كل هذه الأشياء حادّة، فينبغي أن توجد في الحزمة الرئيسية لـ
[01:00] تطبيقنا، وألّا يُطبَّق عليها تقسيم الكود. غير أنّه لدينا أيضًا تهيئة مسارٍ غير حادّة.
[01:08] مثلًا مكوّن المسار (route component) نفسه الذي نُعرّفه كي نصيّر مسارنا، ومكوّن الخطأ (error component)، ومكوّن الانتظار (pending component)، ومكوّن عدم العثور (not found component) وما إلى ذلك. وكود هذه الأشياء غير حادٍّ لمطابقة المسار، ولذلك يمكننا
[01:21] تحميله عند الطلب. يمكننا تقسيمه.
[01:23] فلا نضطر إلى تضمين كل هذه المكوّنات لكل مساراتنا في حزمتنا الرئيسية. وبالطبع يمكنك قراءة المزيد عن تقسيم الكود هنا. غير أنّه لنرَه ربّما قيد العمل بالتوجّه إلى هنا. وما أحتاج إلى فعله هو
[01:38] — تذكّر — في مسار about لدينا، هنا في about، امتلكنا هذا المثال الذي أجرينا فيه إعادة توجيه (redirection) إلى posts، إذ كنّا نجري مجرّد اختبار لمكوّن Navigate هذا، لكن فلنُزل هذا الآن بما أنّنا سنستخدم مسار about في
[01:53] مثالنا. فالآن يمكننا الذهاب إلى about بصورة عادية، والآن لنعُد إلى home، ولنحدّث الصفحة ربّما، ولنفتح تبويب الشبكة (network tab) لَدَينا. فلنفتح تبويب الشبكة هنا. وبما أنّه مفتوحٌ لَدَينا، فلنتنقّل إلى about. وكما
[02:09] ترى، عندما انتقلنا إلى about لم يحدث شيء في شبكتنا. لم يُحمَّل شيء، لأنّنا حاليًا لا نُمكّن تقسيم الكود. فكُل كود مسار about هذا بما فيه مكوّن المسار. وإذا امتلكنا مكوّن عدم العثور
[02:24] وما إلى ذلك، فكُل ذلك سيكون مضمّنًا في الحزمة الرئيسية.
[02:28] لكن يمكننا تمكين تقسيم الكود كي نجعل حزمتنا الرئيسية أبطأ قليلًا — عذرًا، أصغر قليلًا — وأنقسم الكود الخاص بمساراتنا إلى أجزاء أصغر. وللقيام بذلك، يمكننا التوجّه إلى إعدادات Vite لَدَينا. فـ
[02:42] إعدادات Vite، وهنا في TanStack Router يمكننا تمكين تقسيم الكود بإضافة autoCodeSplitting هنا وضبطها على true.
[02:53] بفعل ذلك قد نحتاج إلى إعادة تشغيل الخادم، أو في الواقع يبدو أنها أعدت التشغيل تلقائيًا.
[03:01] والآن لنجرب أن نعود إلى home، ونحدّث، ولنفرّغ تبويب الشبكة لَدَينا، ثم فلنتنقّل الآن إلى about، وكما ترى فلدينا أشياء تحدث هنا. فامتلاكنا مكوّن about محمَّلًا عند الطلب عندما ننتقل إلى
[03:16] about. فكما ترى هنا، امتلكنا مكوّن about. وإذا دقّقنا النظر هنا، فسنجد ربّما مكوّن المسار هنا. وربّما لو بحثتَ عن نص about الذي لَدَينا، فقد نجده فعليًا
[03:31] هنا كذلك. فتذكّر أنّنا امتلكنا هنا وسم h3 بنص about. وهنا — هنا — امتلكنا وسم h3، وامتلكنا نص about وأصنافنا (classes) وما إلى ذلك. فيبدو أنّ كود هذا
[03:47] المكوّن هو ما تحمّل عند الطلب بما أنّنا نُطبّق الآن التقسيم التلقائي للكود (auto code splitting). فلنجرب ذلك كذلك مع مسارٍ آخر، وهذا هو مسار post. فتذكّر أنّ مسار التدوينة الفردية لدينا، وهو posts/post ID، كان به
[04:02] أشياء أخرى. فتذكّر أنّه كانت لَدَينا مكوّن الانتظار أيضًا، وامتلكنا كذلك مكوّن الخطأ ومكوّن عدم العثور. وكل هذه ستُقسَّم هيَ الأخرى بتقسيم الكود. فإذا ذهبنا إلى /posts وجربنا زيارة posts
[04:16] نجرّب زيارة بعض التدوينات الفردية. فلنفرّغ شبكتنا، وفي قائمة التدوينات لَدَينا فلنزُر post one. وكما ترى، فإضافة إلى طلب الشبكة الذي يجلب التدوينة والتعليقات، امتلكنا أيضًا طلبات أخرى لجلب
[04:34] مكوّن التدوينة. وهذه هي المكوّنات الأخرى كذلك: مكوّن الخطأ، ومكوّن عدم العثور، وما إلى ذلك. والآن، لنفرّغ هذا ربّما، ولنعُد، ولنذهب إلى تدوينة أخرى. فلنذهب هنا إلى post
[04:50] two مثلًا. والآن، وكما ترى، نحصل فقط على طلبات الشبكة الخاصة بالتدوينة نفسها والتعليقات، ولم نحصل على الطلبات الخاصة بالمكوّنات. لماذا؟ لأنّ هذه هي المكوّنات نفسها التي استخدمناها عندما
[05:05] حمّلنا post one. تذكّر أنّ post one وpost two كلاهما — كلاهما — يستخدمان المسارَ نفسه والمكوّنات نفسها. فلا نحتاج إلى تحميلها في كل مرة نزور فيها تدوينةً مختلفة.
[05:17] حسنًا. فخلاصةً هذا هو الأمر عمومًا. غير أنّه يمكنك إجراء تخصيصات (customizations) أكثر إن أردت. ففي هذا المكان، وكما ترى في هذه الصفحة من التوثيق (documentation)، يمكننا تخصيص طريقة عمل التقسيم التلقائي للكود بتحديد ما الذي يجب
[05:37] تقسيمه بالضبط. ففي هذا المكان امتلكنا هذه الأشياء التي يمكن تقسيمها: المكوّن الرئيسي (main component) للمسار، ومكوّن الخطأ، ومكوّن الانتظار، ومكوّن عدم العثور؛ فكلها ستُقسَّم افتراضيًا. ويمكننا كذلك تقسيم
[05:50] المُحمِّل كذلك، أي دالة المُحمِّل. لكنّ هذا غير موصى به في الواقع. وإذا نزلنا إلى هنا، فسنرى أمثلة عن تخصيص السلوك، وهو ما يمكننا فعله عالميًا (globally) بالتوجّه إلى إعدادات Vite لَدَينا و
[06:05] تغيير السلوك الافتراضي هنا، أو يمكننا كذلك امتلاك تحكّم برمجي (programmatic) بتمرير دالة بدلًا من ذلك. وهكذا يمكننا فعل الأمر بأسلوبٍ مختلف ربّما لمساراتٍ مختلفة. فيمكننا هنا تمرير دالة — سلوك التقسيم (split behavior) — حيث
[06:16] سنحصل على معرّف المسار (route ID)، وربّما بناءً على المسار نحتاج إلى تقسيم أشياء معينة لهذا المسار. غير أنّه أظنّ أنّ السلوك الافتراضي سيكفي غالبًا في معظم الأوقات. أما ما يمكنك أن تفعله كذلك إن أردت
[06:29] ففي إمكانك أن تجد هذا الرابط هنا حيث يمكنك التحكّم فيما يجب تقسيمه بالضبط إذا كنت لا تستخدم التقسيم التلقائي للكود. فإذا كنت، لسببٍ ما، غير قادرٍ على استخدام ميزة التقسيم التلقائي للكود في إعدادات Vite
[06:45] لديك، فلا يزال بإمكانك تقسيم ملفات المسارات لَدَينا بإضافة اللاحقة lazy.tsx هذه.
[06:53] وامتلكتَ هنا أمثلة عن كيفية فعل ذلك. فمثلًا، هكذا نُعرّف مسارًا بصورة عادية. لكن لنقل أنّنا نودّ تقسيم المكوّن — المكوّن الخاص بالمسار — دون تقسيم المُحمِّل.
[07:07] عندها سنحتاج إلى تقسيم ملفنا — لنقسم هذا الملف إلى ملفَّين.
[07:12] واحد للأشياء الحادّة مثل المُحمِّل في مثالنا، وواحد آخر للأشياء غير الحادّة التي يمكن تقسيمها مثل المكوّن. ففي هذه الحالة سنمتلك ملف posts.tsx هذا الذي سيحتوي المُحمِّل، وملف
[07:25] posts.lazy.tsx حيث سننشئ createLazyFileRoute بدلًا من createFileRoute، ثم نمرّر الأشياء التي نحتاج إلى تقسيمها مثل المكوّن.
[07:37] فهكذا يمكنك فعل ذلك يدويًا إذا كنت لا تُمكّن التقسيم التلقائي للكود لسببٍ ما. غير أنّه بتمكين التقسيم التلقائي للكود سيتحقّق كل ذلك نيابةً عنك في الخفاء لكل مساراتك. والآن وقد عرفنا