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

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

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

  • تحميل الموارد غير المهمة بشكل بطيء

  • الاتصال مسبقًا بالمواقع الإلكترونية المطلوبة

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

  • تضمين فيديو

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

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

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

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

قياس الأداء

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

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

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

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

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

لقطة شاشة لتدقيق Lighthouse تعرِض سرعة عرض المحتوى على الصفحة التي تبلغ 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 مع علامة script مميّزة في العنوان

يمكن لسمتَين سحريتَين إزالة حظر المُحلِّل عند إضافتهما إلى علامة النص البرمجي:

  • يضمن 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. اضغط على Ctrl ‏+ Shift ‏+ J (أو Command ‏+ Option ‏+ J على نظام التشغيل Mac) لفتح DevTools.
  3. انقر على علامة التبويب الشبكة.
  4. ضَع علامة في مربّع الاختيار إيقاف ذاكرة التخزين المؤقت.
  5. اختَر شبكة الجيل الثالث السريعة في القائمة المنسدلة تقييد السرعة.
  6. إعادة تحميل الصفحة

لقطة شاشة للوحة &quot;الشبكة&quot; في 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 لتحميل الفيديو بشكل بطيء

لتحميل الفيديو عندما ينتقل إليه المستخدم، عليك معرفة وقت حدوث ذلك. وهنا يأتي دور واجهة برمجة التطبيقات 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. اضغط على Ctrl ‏+ Shift ‏+ J (أو Command ‏+ Option ‏+ J على نظام التشغيل Mac) لفتح DevTools.
  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