تحسين JavaScript للجهات الخارجية

تؤثر النصوص البرمجية التابعة لجهات خارجية في الأداء، ولذلك من المهم تدقيقها بانتظام واستخدام أساليب فعّالة لتحميلها. يعرض لك هذا الدرس التطبيقي كيفية تحسين تحميل المراجع التابعة لجهات خارجية. ويتناول الأساليب التالية:

  • تأجيل تحميل النص البرمجي

  • تحميل الموارد غير المهمة باستخدام طريقة "التحميل الكسول"

  • جارٍ الاتصال مسبقًا بالمصادر المطلوبة

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

  • تضمين فيديو

  • مكتبة تصور البيانات لعرض رسم بياني خطي

  • تطبيق مصغّر لمشاركة المحتوى على وسائل التواصل الاجتماعي

لقطة شاشة للصفحة تتضمّن مراجع من جهات خارجية مميّزة.
المراجع التابعة لجهات خارجية في نموذج التطبيق

ستبدأ بقياس أداء التطبيق، ثم ستطبِّق كل أسلوب لتحسين الجوانب المختلفة لأداء التطبيق.

قياس الأداء

افتح أولاً نموذج التطبيق في طريقة العرض بملء الشاشة:

  1. انقر على إنشاء ريمكس لتعديل لجعل المشروع قابلاً للتعديل.
  2. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط ملء الشاشة ملء الشاشة

يمكنك إجراء تدقيق أداء Lighthouse على الصفحة لتحديد الأداء الأساسي:

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

عند إجراء عملية تدقيق على جهازك، قد تختلف النتائج الدقيقة، ولكن من المفترض أن تلاحظ أنّ مدة سرعة عرض أوّل محتوى (FCP) مرتفعة جدًا، وتقترح أداة Lighthouse فرصتَين للتحقيق فيهما، وهما: إزالة الموارد التي تحظر العرض والاتصال المسبق بالمصادر المطلوبة. (حتى إذا كانت جميع المقاييس باللون الأخضر، ستظل التحسينات تؤدي إلى تحسينات).

لقطة شاشة لعملية تدقيق في Lighthouse تُظهر 2.4 ثانية من سرعة FCP وفرصتين: إزالة الموارد التي تمنع العرض وميزة "الاتصال المسبق" للأصول المطلوبة

تأجيل لغة JavaScript التابعة لجهات خارجية

حددت عملية التدقيق إزالة الموارد التي تحظر العرض أنه يمكنك توفير بعض الوقت من خلال تأجيل نص برمجي قادم من d3js.org:

لقطة شاشة لتدقيق الموارد التي تحظر العرض مع تمييز النص البرمجي d3.v3.min.js.

D3.js هي مكتبة JavaScript لإنشاء العروض المرئية للبيانات. يستخدم ملف script.js في نموذج التطبيق وظائف الأداة D3 لإنشاء رسم بياني خطي بتنسيق SVG وإلحاقه بالصفحة. من المهم ترتيب العمليات هنا: يجب تشغيل script.js بعد تحليل المستند وتحميل مكتبة D3، ولذلك يتم تضمينها قبل علامة الإغلاق </body> في index.html مباشرةً.

ومع ذلك، يتم تضمين النص البرمجي D3 في <head> للصفحة، ما يمنع تحليل باقي المستند:

لقطة شاشة لملف index.html مع تمييز علامة النص البرمجي في الرأس

يمكن لسمتين سحرية إلغاء حظر المحلل اللغوي عند إضافتهما إلى علامة النص البرمجي:

  • تضمن async تنزيل النصوص البرمجية في الخلفية وتنفيذها في أول فرصة بعد انتهاء تنزيلها.

  • يضمن defer تنزيل النصوص البرمجية في الخلفية وتنفيذها بعد اكتمال التحليل.

بما أنّ هذا الرسم البياني ليس مهمًا للصفحة بأكملها وسيكون على الأرجح الجزء السفلي غير المرئي من الصفحة، يمكنك استخدام defer للتأكّد من عدم حظر المحلِّل اللغوي.

الخطوة 1: تحميل النص البرمجي بشكل غير متزامن مع السمة defer

في السطر 17 من index.html، أضِف السمة defer إلى العنصر <script>:

<script src="https://d3js.org/d3.v3.min.js" defer></script>

الخطوة 2: التأكّد من الترتيب الصحيح للعمليات

الآن بعد تأجيل D3، سيتم تنفيذ script.js قبل أن يصبح D3 جاهزًا، ما يؤدي إلى حدوث خطأ.

يتم تنفيذ النصوص البرمجية التي تتضمّن السمة defer بالترتيب الذي تم تحديدها به. لضمان تنفيذ script.js بعد أن يصبح D3 جاهزًا، أضِف defer إليه وانقله إلى <head> في المستند، بعد عنصر <script> D3 مباشرةً. والآن لم يعد يحظر المحلل اللغوي، وسيبدأ التنزيل بشكل أسرع.

<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>

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

تكون جميع الموارد المتوفّرة في الجزء السفلي غير المرئي من الصفحة مناسبة تمامًا للتحميل الكسول.

يحتوي نموذج التطبيق على فيديو YouTube مضمّن في iframe. للاطّلاع على عدد الطلبات التي ترسلها الصفحة وتلك التي يتم الحصول عليها من إطار iframe في YouTube، يُرجى اتّباع الخطوات التالية:

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

لقطة شاشة للوحة شبكة DevTools

تكشف لوحة الشبكة أنّ الصفحة قدّمت 28 طلبًا إجمالاً ونقلت 1 ميغابايت تقريبًا من الموارد المضغوطة.

لتحديد الطلبات المقدَّمة من "iframe" على YouTube، ابحث عن معرّف الفيديو 6lfaiXM6waw في عمود المبدئ. لتجميع كل الطلبات معًا حسب النطاق:

  • في لوحة الشبكة، انقر بزر الماوس الأيمن على عنوان عمود.

  • في القائمة المنسدلة، اختَر عمود النطاقات.

  • لترتيب الطلبات حسب النطاق، انقر على عنوان عمود النطاقات.

يكشف الترتيب الجديد عن وجود طلبات إضافية لنطاقات Google. يقدم إطار iframe في YouTube إجمالاً 14 طلبًا للنصوص البرمجية وأوراق الأنماط والصور والخطوط. ولكن ما لم يقوم المستخدمون بالتمرير لأسفل لتشغيل الفيديو، فلن يحتاجون حقًا إلى كل مواد العرض هذه.

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

ويتم تنفيذ طريقة "التحميل الكسول" من خلال استخدام Intersection Observer، وهي واجهة برمجة تطبيقات خاصة بالمتصفّح تُعلِمك عند دخول عنصر إلى إطار عرض المتصفّح أو الخروج منه.

الخطوة 1: منع تحميل الفيديو في البداية

لإجراء تحميل كسول لإطار iframe للفيديو، عليك أولاً منع تحميله بالطريقة المعتادة. يمكنك إجراء ذلك من خلال استبدال السمة src بالسمة data-src لتحديد عنوان URL الخاص بالفيديو:

<iframe width="560" height="315" data-src="https://www.youtube.com/embed/lS9D6w1GzGY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

data-src هي سمة بيانات تتيح لك تخزين معلومات إضافية على عناصر HTML العادية. يمكن تسمية سمة البيانات بأي شيء، طالما أنها تبدأ بـ "data-".

يتعذّر تحميل إطار iframe بدون src.

الخطوة 2: استخدام أداة "مراقبة التقاطع" لتحميل الفيديو الكسول

عليك معرفة وقت حدوث ذلك لتحميل الفيديو عندما ينتقل المستخدم إليه. وهنا يأتي دور واجهة برمجة تطبيقات Intersection Observer API. تتيح لك Intersection Observer API تسجيل دالة استدعاء يتم تنفيذها عندما يدخل عنصر تريد تتبُّعه إلى إطار العرض أو يخرج منه.

للبدء، يجب إنشاء ملف جديد وتسميته باسم lazy-load.js:

  • انقر على ملف جديد وأدخِل اسمًا له.
  • انقر على إضافة هذا الملف.

أضف علامة النص البرمجي إلى رأس المستند:

 <script src="/lazy-load.js" defer></script>

في lazy-load.js، أنشئ IntersectionObserver جديدة وأرسِلها كدالة استدعاء لتشغيلها:

// create a new Intersection Observer
let observer = new IntersectionObserver(callback);

يمكنك الآن منح observer عنصرًا مستهدفًا لمشاهدته (إطار iframe للفيديو في هذه الحالة) من خلال تمريره كوسيطة في طريقة observe:

// the element that you want to watch
const element = document.querySelector('iframe');

// register the element with the observe method
observer.observe(element);

تتلقّى callback قائمة بكائنات IntersectionObserverEntry والكائن IntersectionObserver نفسه. يحتوي كل إدخال على عنصر target وخصائصه التي تصف أبعاده وموضعه ووقت دخوله إلى إطار العرض، وغيرها. إحدى سمات IntersectionObserverEntry هي isIntersecting، وهي قيمة منطقية تساوي true عندما يدخل العنصر إلى إطار العرض.

في هذا المثال، تمثّل السمة target السمة iframe. تساوي isIntersecting true عندما تدخل target في إطار العرض. للاطّلاع على ذلك عمليًا، استبدِل callback بالدالة التالية:

let observer = new IntersectionObserver(callback);
let observer = new IntersectionObserver(function(entries, observer) {
    entries.forEach(entry => {
      console.log(entry.target);
      console.log(entry.isIntersecting);
    });
  });
  1. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط ملء الشاشة ملء الشاشة
  2. اضغط على "Control+Shift+J" (أو "Command+Option+J" على أجهزة Mac) لفتح "أدوات مطوري البرامج".
  3. انقر على علامة التبويب وحدة التحكم.

جرِّب الانتقال للأعلى وللأسفل. من المفترض أن تظهر لك قيمة التغيير isIntersecting والعنصر الهدف المسجَّل في وحدة التحكّم.

لتحميل الفيديو عندما ينتقل المستخدم إلى موضعه، استخدِم isIntersecting كشرط لتشغيل الدالة loadElement التي تحصل على القيمة من data-src في العنصر iframe وتضبطها كسمة src للعنصر iframe. يؤدي هذا الاستبدال إلى تحميل الفيديو. بعد ذلك، بعد تحميل الفيديو، يمكنك استدعاء الإجراء unobserve على observer للتوقّف عن مشاهدة العنصر الهدف:

let observer = new IntersectionObserver(function (entries, observer) {
  entries.forEach(entry => {
    console.log(entry.target);
    console.log(entry.isIntersecting);
  });
});
    if (entry.isIntersecting) {
      // do this when the element enters the viewport
      loadElement(entry.target);
      // stop watching
      observer.unobserve(entry.target);
    }
  });
});

function loadElement(element) {
  const src = element.getAttribute('data-src');
  element.src = src;
}

الخطوة 3: إعادة تقييم الأداء

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

الآن انتقِل إلى أسفل الصفحة وراقِب لوحة الشبكة. عندما تصل إلى الفيديو، من المفترض أن تظهر الصفحة تطلب منك إرسال طلبات إضافية.

الاتصال المسبق بالمصادر المطلوبة

لقد أجَّلت محتوى JavaScript غير المهم وحمّلت طلبات YouTube بشكل كسول، لذا حان الوقت الآن لتحسين المحتوى المتبقي التابع لجهات خارجية.

عند إضافة السمة rel=preconnect إلى رابط، يتم توجيه المتصفّح لإنشاء اتصال بنطاق قبل تقديم طلب الوصول إلى هذا المورد. يتم استخدام هذه السمة بشكل أفضل مع المصادر التي توفّر الموارد التي تحتاجها الصفحة.

تدقيق Lighthouse الذي أجريته في الخطوة الأولى، والذي اقترحه في الاتصال المسبق بالمصادر المطلوبة، والذي يمكنك توفيره حوالي 400 ملي ثانية من خلال إنشاء اتصالات مبكرة بكل من staticxx.facebook.com وyoutube.com:

الاتصال مسبقًا بتدقيق المصادر المطلوبة مع تمييز النطاق staticxx.facebook.com.

ولأنّ الفيديو على YouTube أصبح الآن بالتحميل الكسول، ما يعني أنّ الموقع الإلكتروني staticxx.facebook.com هو مصدر أداة المشاركة على وسائل التواصل الاجتماعي. يمكن إنشاء اتصال مبكرًا بهذا النطاق بسهولة من خلال إضافة علامة <link> إلى العنصر <head> في المستند:

  <link rel="preconnect" href="https://staticxx.facebook.com">

إعادة تقييم الأداء

في ما يلي حالة الصفحة بعد التحسين. اتّبِع الخطوات الواردة في قسم قياس الأداء في الدرس التطبيقي حول الترميز لإجراء تدقيق آخر في Lighthouse.

تدقيق من خلال Lighthouse يُظهر FCP ثانية واحدة ونتيجة الأداء 99.