تقليل حمولات JavaScript من خلال تقسيم الرمز

تتكون معظم صفحات الويب والتطبيقات من أجزاء مختلفة عديدة. بدلاً من إرسال كل عناصر جافا سكريبت التي تتألف منها التطبيق بأسرع وقت ممكن تحميل صفحة، وتقسيم JavaScript إلى أجزاء متعددة على تحسين أداء الصفحة.

يعرض هذا الدرس التطبيقي حول الترميز كيفية استخدام تقسيم الرموز لتحسين أداء تطبيق بسيط يفرز ثلاثة أرقام.

نافذة متصفّح تعرض تطبيقًا بعنوان "أداة الترتيب السحرية" يتضمّن ثلاثة حقول لإدخال الأرقام وزر الترتيب

القياس

كما هو الحال دائمًا، من المهم قياس مستوى أداء موقع الويب قبل محاولة إضافة أي تحسينات.

  1. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط ملء الشاشة ملء الشاشة
  2. اضغط على "Control+Shift+J" (أو "Command+Option+J" على أجهزة Mac) لفتح "أدوات مطوري البرامج".
  3. انقر على علامة التبويب الشبكة.
  4. ضع علامة في مربّع الاختيار إيقاف ذاكرة التخزين المؤقت.
  5. أعِد تحميل التطبيق.

لوحة في الشبكة تعرض حزمة JavaScript بحجم 71.2 كيلوبايت

حجم 71.2 كيلوبايت من JavaScript فقط لفرز بضعة أرقام في تطبيق بسيط. What gives?

في رمز المصدر (src/index.js)، يتم استيراد مكتبة lodash واستخدامها. في هذا التطبيق. توفر Lodash العديد من الأدوات المفيدة ولكن يتم استخدام طريقة واحدة فقط من الحزمة هنا. تثبيت واستيراد تبعيات الجهات الخارجية الكاملة، حيث لا يكون هناك سوى جزء من حيث يتم استخدام جزء منه يعد خطأ شائعًا.

تحسين

في ما يلي بعض الطرق التي يمكن من خلالها اقتطاع حجم الحزمة:

  1. كتابة طريقة ترتيب مخصّصة بدلاً من استيراد مكتبة تابعة لجهة خارجية
  2. استخدِم طريقة Array.prototype.sort() المضمَّنة لترتيب البيانات بالأرقام.
  3. استيراد طريقة sortBy من lodash فقط وليس من المكتبة بأكملها
  4. لا تنزِّل الرمز للترتيب إلا عندما ينقر المستخدم على الزر.

يُعد الخياران 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>
  `
});

أعِد تحميل التطبيق وافتح "أدوات مطوري البرامج" وألق نظرة على لوحة الشبكة. مرة أخرى.

لوحة في الشبكة تعرض حزمة JavaScript بحجم 15.2 كيلوبايت

وبالنسبة إلى هذا التطبيق، تم تقليل حجم الحزمة بما يزيد عن 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>
    `
  };
}

مراقب

أعِد تحميل التطبيق للمرة الأخيرة وراقب الشبكة عن كثب. اللوحة مرة أخرى. يتم تنزيل حزمة أولية صغيرة فقط بعد تنزيل التطبيق التحميل.

لوحة شبكة تعرض حزمة JavaScript بحجم 2.7 كيلوبايت

بعد الضغط على الزر لفرز أرقام الإدخال، فإن المقطع الذي يحتوي على يتم استرجاع رمز الفرز وتنفيذه.

لوحة شبكة تعرض حزمة JavaScript بحجم 2.7 كيلوبايت متبوعة بحزمة JavaScript بحجم 13.9 كيلوبايت.

لاحظ كيف لا يزال يتم فرز الأرقام!

الخاتمة

يمكن أن يكون تقسيم الرموز والتحميل الكسول أسلوبَين مفيدَين للغاية لتقليل. الحجم الأولي للحزمة لتطبيقك، وقد ينتج عن ذلك بشكل مباشر في أوقات تحميل الصفحات بسرعة أكبر بكثير. ومع ذلك، هناك بعض الأشياء المهمة التي تحتاج لأخذه في الاعتبار قبل تضمين هذا التحسين في تطبيقك.

واجهة مستخدم التحميل الكسول

عند التحميل الكسول لوحدات محددة من الرمز، من المهم التفكير في كيفية المستخدمين الذين لديهم اتصالات شبكة أضعف. يُعد التقسيم فإن تحميل مقطع كبير جدًا من التعليمات البرمجية عندما يرسل المستخدم إجراءً ما يمكن أن يجعله يبدو أنّ التطبيق قد توقّف عن العمل، لذا نقترح عليك عرض مؤشر تحميل من نوع ما.

وحدات العُقد التابعة لجهات خارجية ذات التحميل الكسول

ثم لا يُفضل دائمًا التحميل الكسول لتبعيات الجهات الخارجية في يعتمد ذلك على المكان الذي تستخدمه فيه. عادةً، طرف ثالث يتم تقسيم الموارد التابعة إلى حزمة vendor منفصلة يمكن تخزينها مؤقتًا. لا يتم تحديثها كثيرًا. يمكنك قراءة المزيد عن كيفية يمكن لـ SplitChunksPlugin أن سيساعدك على القيام بذلك.

التحميل الكسول باستخدام إطار عمل JavaScript

يوفر العديد من أطر العمل والمكتبات الشائعة التي تستخدم حزمة الويب تجريدات "التحميل الكسول" أسهل من استخدام عمليات الاستيراد الديناميكية في منتصف التطبيق.

على الرغم من أهمية فهم كيفية عمل عمليات الاستيراد الديناميكية، استخدم دائمًا الذي يقترحه إطار العمل/المكتبة للتحميل الكسول لوحدات معيّنة.

التحميل المسبق والجلب المسبق

استفِد قدر الإمكان من تلميحات المتصفّح، مثل <link rel="preload">. أو <link rel="prefetch"> لمحاولة تحميل الوحدات المُهمة قريبًا. تدعم webpack كلا التلميحين من خلال استخدام التعليقات السحرية في الاستيراد. البيانات. ويتوفّر المزيد من التفاصيل في دليل التحميل المُسبق للأجزاء المهمة.

طريقة "التحميل الكسول" تتجاوز الترميز

يمكن أن تشكّل الصور جزءًا كبيرًا من التطبيق. التحميل الكسول لتلك التي موجودة في الجزء السفلي غير المرئي من الصفحة أو خارج إطار عرض الجهاز، يمكن أن تُسرِّع أداء موقع الويب. القراءة المزيد عن هذا في دليل الأحجام الكسولة.