لا أحد يحب الانتظار. يغادر أكثر من %50 من المستخدمين الموقع الإلكتروني إذا استغرق تحميله أكثر من 3 ثوانٍ.
عند إرسال أحمال JavaScript كبيرة، يؤثر ذلك بشكل كبير في سرعة موقعك الإلكتروني. بدلاً من إرسال كل ملف JavaScript إلى المستخدم فور تحميل الصفحة الأولى من تطبيقك، يمكنك تقسيم حِزمتك إلى أجزاء متعددة وإرسال ما هو ضروري فقط في البداية.
ما هي فوائد تقسيم الرموز البرمجية؟
إنّ تقسيم الرموز البرمجية هو أسلوب يهدف إلى تقليل وقت بدء التشغيل. عندما يتم توفير عدد أقل من JavaScript عند بدء التشغيل، يمكننا جعل التطبيقات تفاعلية بشكل أسرع من خلال تقليل سلسلة التعليمات الرئيسية خلال هذه الفترة الحرجة.
في ما يتعلّق بمؤشرات أداء الويب الأساسية، سيؤدي تقليل حِزم JavaScript التي يتم تنزيلها عند بدء التشغيل إلى تحسين أوقات مدى استجابة الصفحة لتفاعلات المستخدم (INP). والسبب في ذلك هو أنّه من خلال تحرير سلسلة المحادثات الرئيسية، يتمكّن التطبيق من الاستجابة لبيانات المستخدمين بشكل أسرع من خلال تقليل تكاليف بدء التشغيل المرتبطة بتحليل JavaScript وترجمته وتنفيذه.
استنادًا إلى بنية موقعك الإلكتروني، لا سيما إذا كان موقعك الإلكتروني يعتمد بشكل كبير على العرض من جهة العميل، قد يؤدي تقليل حجم حِزم JavaScript المسؤولة عن عرض العلامات إلى تحسين أوقات سرعة عرض أكبر محتوى مرئي (LCP). يمكن أن يحدث ذلك عندما يتأخّر اكتشاف مَعلمة LCP من قِبل المتصفّح إلى أن يكتمل ترميز جهة العميل، أو عندما يكون الخيط الرئيسي مشغولاً جدًا لعرض عنصر LCP هذا. يمكن أن يؤدي كلا السيناريوهَين إلى تأخير وقت LCP للصفحة.
القياس
يعرض Lighthouse تقرير تدقيق تعذّر إجراؤه عندما يستغرق تنفيذ كل JavaScript على الصفحة وقتًا طويلاً.
يمكنك تقسيم حِزمة JavaScript لإرسال الرمز المطلوب فقط للمسار الأوّلي عندما يُحمِّل المستخدِم أحد التطبيقات. ويقلل هذا من مقدار النصوص البرمجية التي يجب تحليلها وتجميعها، ما يؤدي إلى زيادة سرعة تحميل الصفحة.
تسمح لك حِزم الوحدات الرائجة، مثل webpack
وParcel
وRollup، بتقسيم الحِزم باستخدام عمليات الاستيراد الديناميكية.
على سبيل المثال، راجِع المقتطف التالي من الرمز البرمجي الذي يعرض مثالاً على someFunction
يتم تشغيله عند إرسال نموذج.
import moduleA from "library";
form.addEventListener("submit", e => {
e.preventDefault();
someFunction();
});
const someFunction = () => {
// uses moduleA
}
في هذا المثال، يستخدم someFunction
وحدة مستورَدة من مكتبة معيّنة. إذا كانت
هذه الوحدة غير مستخدَمة في مكان آخر، يمكن تعديل مجموعة الرموز البرمجية لاستخدام عملية إعلام ديناميكية لاستردادها فقط عندما يرسل المستخدم النموذج.
form.addEventListener("submit", e => {
e.preventDefault();
import('library.moduleA')
.then(module => module.default) // using the default export
.then(() => someFunction())
.catch(handleError());
});
const someFunction = () => {
// uses moduleA
}
لا يتم تضمين الرمز الذي يشكّل الوحدة في الحزمة الأولية، ويتم الآن تحميله بشكل بطيء، أو لا يتم تقديمه للمستخدم إلا عند الحاجة إليه بعد إرسال النموذج. لتحسين أداء الصفحة بشكل أكبر، يمكنك تحميل الأجزاء المهمة مسبقًا لتحديد أولوياتها واستردادها في وقت أقرب.
على الرغم من أنّ مقتطف الرمز السابق هو مثال بسيط، إلا أنّ تحميل العناصر الخارجية بشكلٍ بطيء ليس نمطًا شائعًا في التطبيقات الأكبر حجمًا. عادةً ما يتم تقسيم التبعيات التابعة لجهة خارجية إلى حِزمة مورّد منفصلة يمكن تخزينها مؤقتًا لأنّها لا يتم تحديثها بشكل متكرّر. يمكنك الاطّلاع على المزيد من المعلومات حول الإجراءات التي يمكن أن تساعدك بها طريقة يضم تقسيمًا للمكوّن الإضافي في تنفيذ هذا الإجراء.
يُعد التقسيم على مستوى المسار أو المكون عند استخدام إطار عمل من جهة العميل طريقة أبسط للتحميل الكسول لأجزاء مختلفة من التطبيق. توفِّر العديد من أطر العمل الرائجة التي تستخدم حِزمة الويب تجريدات لتسهيل عملية "التحميل الكسول" عن إجراء عمليات الضبط بنفسك.