تؤثّر النصوص البرمجية التابعة لجهات خارجية في الأداء، لذلك من المهم تدقيقها بانتظام واستخدام تقنيات فعّالة لتحميلها. يوضّح لك هذا الدليل التعليمي حول الرموز البرمجية كيفية تحسين تحميل الموارد التابعة لجهات خارجية. ويتناول هذا الدليل الأساليب التالية:
تأجيل تحميل النصوص البرمجية
تحميل الموارد غير المهمة بشكل كسول
الاتصال مسبقًا بالمواقع الإلكترونية المطلوبة
يعرض نموذج التطبيق المضمّن صفحة ويب بسيطة تتضمّن ثلاث ميزات من مصادر تابعة لجهات خارجية:
تضمين فيديو
مكتبة لتصور البيانات لعرض رسم بياني خطي
تطبيق مصغّر لمشاركة المحتوى على وسائل التواصل الاجتماعي
ستبدأ بقياس أداء التطبيق ثم ستطبّق كل تقنية لتحسين جوانب مختلفة من أداء التطبيق.
قياس الأداء
افتح أولاً نموذج التطبيق في وضع ملء الشاشة:
- انقر على Remix to Edit (إنشاء ريمكس لتعديل المحتوى) ليصبح المشروع قابلاً للتعديل.
- لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط على ملء الشاشة .
يمكنك إجراء تدقيق أداء Lighthouse على الصفحة لتحديد مستوى الأداء الأساسي:
- اضغط على Ctrl + Shift + J (أو Command + Option + J على نظام التشغيل Mac) لفتح DevTools.
- انقر على علامة التبويب Lighthouse.
- انقر على الأجهزة الجوّالة.
- ضَع علامة في مربّع الاختيار الأداء. (يمكنك محو بقية مربّعات الاختيار في قسم "عمليات التدقيق").
- انقر على شبكة الجيل الثالث السريعة المحاكية، ووحدة المعالجة المركزية (CPU) أبطأ بأربعة أضعاف.
- ضَع علامة في مربّع الاختيار محو مساحة التخزين.
- انقر على تنفيذ عمليات التدقيق.
عند إجراء تدقيق على جهازك، قد تختلف النتائج الدقيقة، ولكن من المفترض أن تلاحظ أنّ وقت عرض أول محتوى مرئي (FCP) مرتفع جدًا، وأنّ Lighthouse تقترح فرصتَين للتحقيق: التخلص من الموارد التي تمنع العرض والربط المُسبَق بالمصادر المطلوبة. (حتى إذا كانت جميع المقاييس في وضع جيد، سيستمرّ تطبيق التحسينات في تحقيق تحسينات).
تأجيل JavaScript التابع لجهة خارجية
رصدت عملية تدقيق إزالة الموارد التي تحظر العرض أنّه يمكنك توفير بعض الوقت من خلال تأجيل نص برمجي قادم من d3js.org:
D3.js هي مكتبة JavaScript لإنشاء تصورات البيانات. يستخدم ملف script.js
في نموذج التطبيق دوالّ أداة D3 لإنشاء المخطّط الخطي بتنسيق SVG وإرفاقه بالصفحة. من المهمّ ترتيب العمليات هنا: يجب تنفيذ script.js
بعد تحليل المستند وتحميل مكتبة D3، ولهذا السبب يتم تضمينها قبل علامة </body>
الإغلاق مباشرةً في index.html
.
ومع ذلك، يتم تضمين نص D3 البرمجي في <head>
الصفحة، ما يؤدي إلى حظر تحليل باقي المستند:
يمكن لسمتَين سحريتَين إزالة حظر المُحلِّل عند إضافتهما إلى علامة النص البرمجي:
يضمن
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، اتّبِع الخطوات التالية:
- لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط على ملء الشاشة .
- اضغط على Ctrl + Shift + J (أو Command + Option + J على نظام التشغيل Mac) لفتح 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);
});
});
- لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط على ملء الشاشة .
- اضغط على Ctrl + Shift + J (أو Command + Option + J على نظام التشغيل Mac) لفتح DevTools.
- انقر على علامة التبويب وحدة التحكم.
جرِّب الانتقال للأعلى أو للأسفل. من المفترض أن تلاحظ تغيُّر قيمة 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:
بما أنّ فيديو YouTube يتم تحميله الآن بشكل بطيء، لن يتبقّى سوى staticxx.facebook.com، وهو مصدر التطبيق المصغّر لمشاركة المحتوى على وسائل التواصل الاجتماعي. يمكنك بسهولة إنشاء ربط مبكر بهذا النطاق من خلال إضافة علامة <link>
إلى <head>
المستند:
<link rel="preconnect" href="https://staticxx.facebook.com">
إعادة تقييم الأداء
في ما يلي حالة الصفحة بعد التحسين. اتّبِع الخطوات الواردة في قسم قياس الأداء من ورشة رموز البرامج لإجراء عملية تدقيق أخرى في Lighthouse.