تتألف معظم صفحات الويب والتطبيقات من عدة أجزاء مختلفة. بدلاً من إرسال كل رمز JavaScript الذي يشكّل التطبيق فور تحميل الصفحة الأولى، يؤدي تقسيم رمز JavaScript إلى أجزاء متعددة إلى تحسين أداء الصفحة.
يوضّح هذا الدرس التطبيقي حول الترميز كيفية استخدام تقسيم الرموز البرمجية لتحسين أداء تطبيق بسيط يُرتّب ثلاثة أرقام.
القياس
كما هو الحال دائمًا، من المهم أولاً قياس مستوى أداء الموقع الإلكتروني قبل محاولة إضافة أي تحسينات.
- لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط على ملء الشاشة .
- اضغط على Ctrl + Shift + J (أو Command + Option + J على نظام التشغيل Mac) لفتح DevTools.
- انقر على علامة التبويب الشبكة.
- ضَع علامة في مربّع الاختيار إيقاف ذاكرة التخزين المؤقت.
- أعِد تحميل التطبيق.
71.2 كيلوبايت من JavaScript لترتيب بعض الأرقام في تطبيق بسيط What gives?
في رمز المصدر (src/index.js
)، يتم استيراد مكتبة lodash
واستخدامها
في هذا التطبيق. توفّر مكتبة Lodash العديد من الدوالّ المساعدة المُفيدة، ولكن يتم استخدام طريقة واحدة فقط من الحزمة هنا.
إنّ تثبيت واستخدام مكتبات تابعة لجهات خارجية بالكامل في حال استخدام جزء صغير فقط منها هو خطأ شائع.
تحسين
هناك بضع طرق لتقليل حجم الحِزمة:
- كتابة طريقة ترتيب مخصّصة بدلاً من استيراد مكتبة تابعة لجهة خارجية
- استخدام طريقة
Array.prototype.sort()
المضمّنة للترتيب رقميًا - استيراد طريقة
sortBy
فقط منlodash
وليس المكتبة بأكملها - لا تحمِّل رمز الترتيب إلا عندما ينقر المستخدم على الزر.
الخياران 1 و2 هما طريقتان مناسبتان تمامًا لتقليل حجم الحِزمة (وهما سيُعدّان الخيارَين الأكثر منطقية لتطبيق حقيقي). ومع ذلك، لن يتم استخدام هذه الأدوات في هذا الدليل التعليمي لأغراض تعليمية 😈.
يساعد الخياران 3 و4 في تحسين أداء هذا التطبيق. تتناول الأقسام القليلة التالية من هذا الدليل التعليمي هذه الخطوات. مثل أي دورة تدريبية لترميز، حاوِل دائمًا كتابة الرمز بنفسك بدلاً من نسخه ولصقه.
استيراد ما تحتاج إليه فقط
يجب تعديل بعض الملفات لاستيراد الطريقة الوحيدة من lodash
فقط.
في البداية، استبدِل هذا الاعتماد في package.json
:
"lodash": "^4.7.0",
من خلال تنفيذ ما يلي:
"lodash.sortby": "^4.7.0",
الآن في src/index.js
، استورِد هذه الوحدة المحدّدة:
import "./style.css";
import _ from "lodash";
import sortBy from "lodash.sortby";
عدِّل طريقة ترتيب القيم:
form.addEventListener("submit", e => {
e.preventDefault();
const values = [input1.valueAsNumber, input2.valueAsNumber, input3.valueAsNumber];
const sortedValues = _.sortBy(values);
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
});
أعِد تحميل التطبيق وافتح "أدوات مطوّري البرامج"، ثم اطّلِع على لوحة الشبكة مجددًا.
بالنسبة إلى هذا التطبيق، تم تقليل حجم الحِزمة بأكثر من 4 مرات من خلال جهد بسيط جدًا، ولكن لا يزال هناك مجال للتحسين.
تقسيم الرموز البرمجية
webpack هو أحد أكثر أدوات تجميع الوحدات المفتوحة المصدر استخدامًا اليوم. بعبارة أخرى، تجمّع هذه الأداة جميع وحدات JavaScript (بالإضافة إلى مواد العرض الأخرى) التي تشكّل تطبيق ويب في ملفات ثابتة يمكن للمتصفّح قراءة محتواها.
يمكن تقسيم الحِزمة الواحدة المستخدَمة في هذا التطبيق إلى مقطعَين مختلفَين:
- مسؤول عن الرمز البرمجي الذي يشكّل مسارنا الأولي
- مقطع ثانوي يحتوي على رمز التصنيف
باستخدام عمليات الاستيراد الديناميكية، يمكن تحميل قطعة ثانوية بشكل كسول أوتحميلها عند الطلب. في هذا التطبيق، لا يمكن تحميل الرمز الذي يشكّل المقطع إلا عندما يضغط المستخدم على الزر.
ابدأ بإزالة الاستيراد من المستوى الأعلى لطريقة الترتيب في src/index.js
:
import sortBy from "lodash.sortby";
واستورِده ضمن أداة معالجة الحدث التي يتم تفعيلها عند الضغط على الزر:
form.addEventListener("submit", e => {
e.preventDefault();
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
تشكّل ميزة import()
جزءًا من
اقتراح (في المرحلة
3 حاليًا من عملية TC39) لتضمين إمكانية استيراد وحدة ديناميكيًا.
سبق أن ضمّن webpack ميزة تتيح ذلك ويتّبع البنية النحوية نفسها التي وضعها المقترح.
تعرض import()
وعدًا، وعند حلّه، يتم توفير العبارة
المحدّدة التي يتم تقسيمها إلى جزء منفصل. بعد عرض الوحدات، يتم استخدام module.default
للإشارة إلى عملية التصدير الافتراضية التي يوفّرها lodash. يتم ربط الوعد بسلسلة أخرى من .then
التي
تستدعي طريقة sortInput
لترتيب قيم الإدخال الثلاث. في نهاية سلسلة الوعد،يتم استخدام catch()
للتعامل مع الحالات التي يتم فيها رفض الوعد
بسبب خطأ.
آخر إجراء يجب اتّخاذه هو كتابة طريقة sortInput
في
نهاية الملف. يجب أن تكون هذه دالة تعرِض دالة
تستخدِم الطريقة المستورَدة من lodash.sortBy
. يمكن بعد ذلك للدالة المتداخلة
ترتيب قيم الإدخال الثلاث وتعديل نموذج DOM.
const sortInput = () => {
return (sortBy) => {
const values = [
input1.valueAsNumber,
input2.valueAsNumber,
input3.valueAsNumber
];
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
};
}
مراقب
أعِد تحميل التطبيق مرة أخيرة وانتبِه جيدًا إلى لوحة الشبكة مرة أخرى. يتم تنزيل حزمة أولية صغيرة فقط فور تثبيت التطبيق.
بعد الضغط على الزر لترتيب الأرقام التي تم إدخالها، يتم جلب المقطع الذي يحتوي على رمز الترتيب وتنفيذه.
لاحظ كيف يتم ترتيب الأرقام.
الخاتمة
يمكن أن تكون تقسيم الرموز البرمجية والتحميل غير المتزامن من الأساليب المفيدة للغاية لتقليل حجم الحِزمة الأولي لتطبيقك، ويمكن أن يؤدي ذلك مباشرةً إلى تقليل أوقات تحميل الصفحة بشكلٍ كبير. ومع ذلك، هناك بعض الأمور المهمة التي يجب مراعاتها قبل تضمين هذا التحسين في تطبيقك.
واجهة مستخدم التحميل الكسول
عند تحميل وحدات معيّنة من الرموز البرمجية بشكلٍ بطيء، من المهمّ مراعاة التجربة التي سيحظى بها المستخدمون الذين لديهم اتصالات شبكة أضعف. إنّ تقسيم قطعة كبيرة جدًا من الرمز البرمجي وتحميلها عندما يُرسِل المستخدم إجراءً قد يُعطي انطباعًا بأنّ التطبيق قد توقّف عن العمل، لذا ننصحك بعرض مؤشر تحميل من نوع ما.
تحميل وحدات العقد التابعة لجهات خارجية بشكل كسول
لا يُعدّ التحميل البطيء للموارد التابعة لجهات خارجية في
تطبيقك هو النهج الأفضل في جميع الأوقات، ويعتمد ذلك على مكان استخدامها. يتم عادةً تقسيم التبعيات
التابعة لجهات خارجية إلى حِزمة vendor
منفصلة يمكن تخزينها مؤقتًا في الذاكرة، لأنّه تتم تحديثها بمعدل أقل. اطّلِع على مزيد من المعلومات حول كيفية مساعدة الإضافة
SplitChunksPlugin في
تنفيذ ذلك.
التحميل الكسول باستخدام إطار عمل JavaScript
توفّر العديد من الإطارات والمكتبات الشائعة التي تستخدِم webpack أدوات مجردة لجعل التحميل البطيء أسهل من استخدام عمليات الاستيراد الديناميكية في منتصف تطبيقك.
- تحميل الوحدات بشكل كسول باستخدام Angular
- تقسيم الرموز باستخدام React Router
- التحميل الكسول باستخدام Vue Router
على الرغم من أنّه من المفيد فهم آلية عمل عمليات الاستيراد الديناميكية، استخدِم دائمًا الطريقة التي ينصح بها إطار العمل أو المكتبة لتحميل وحدات معيّنة بشكل بطيء.
التحميل المُسبَق والجلب المُسبَق
استفِد من نصائح المتصفّح كلما أمكن، مثل <link rel="preload">
أو <link rel="prefetch">
لمحاولة تحميل الوحدات المهمة بشكلٍ
أسرع. يتوافق Webpack مع كلتا النصيحتَين من خلال استخدام التعليقات السحرية في عبارات المعالجة. يمكنك الاطّلاع على مزيد من التفاصيل في دليل
تحميل الأجزاء المهمة مسبقًا.
التحميل الكسول أكثر من مجرد رمز
يمكن أن تشكّل الصور جزءًا مهمًا من التطبيق. يمكن أن يؤدي التحميل الكسول للعناصر التي تظهر أسفل الصفحة أو خارج إطار عرض الجهاز إلى تسريع موقع إلكتروني. يمكنك الاطّلاع على مزيد من المعلومات حول ذلك في دليل Lazysizes.