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

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

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

  • يتم التحميل الكسول للموارد غير المهمة

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

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

  • تضمين فيديو

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

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

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

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

قياس الأداء

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

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

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

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

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

لقطة شاشة لتدقيق Lighthouse يظهر في مقياس FCP ومدته 2.4 ثانية وفرصتان: التخلص من موارد حظر العرض والاتصال المسبق بالمصادر المطلوبة.

تأجيل ملفات 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> من المستند، مباشرةً بعد عنصر D3 <script>. والآن لم يعد يحظر المحلل اللغوي، وسيبدأ التنزيل في وقت أقرب.

<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. اختَر الجيل الثالث السريع في القائمة المنسدلة تقييد.
  6. إعادة تحميل الصفحة

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

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

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

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

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

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

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

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

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

الخطوة 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 Monitorer. تتيح لك واجهة برمجة تطبيقات Intersection Monitorer تسجيل وظيفة معاودة الاتصال التي يتم تنفيذها عندما يدخل أحد العناصر التي تريد تتبّعها إلى إطار العرض أو يخرج منه.

للبدء، عليك إنشاء ملف جديد وتسميته 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 يظهر في ثانية واحدة من سرعة عرض المحتوى على الصفحة ونتيجة الأداء 99.