تؤثر النصوص البرمجية التابعة لجهات خارجية في الأداء، ولذلك من المهم تدقيقها بانتظام واستخدام أساليب فعّالة لتحميلها. يوضّح لك هذا الدليل التعليمي كيفية تحسين تحميل الموارد التابعة لجهات خارجية. ويتناول هذا الدليل الأساليب التالية:
تأجيل تحميل النص البرمجي
تحميل الموارد غير المهمة بشكل بطيء
جارٍ الاتصال مسبقًا بالمصادر المطلوبة
يعرض نموذج التطبيق المضمّن صفحة ويب بسيطة تتضمّن ثلاث ميزات من مصادر تابعة لجهات خارجية:
تضمين فيديو
مكتبة لتصور البيانات لعرض رسم بياني خطي
تطبيق مصغّر لمشاركة المحتوى على وسائل التواصل الاجتماعي
ستبدأ بقياس أداء التطبيق ثم ستطبّق كل تقنية لتحسين جوانب مختلفة من أداء التطبيق.
قياس الأداء
افتح أولاً نموذج التطبيق في وضع ملء الشاشة:
- انقر على 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>
في المستند، بعد عنصر <script>
D3 مباشرةً. لم يعُد الآن يحظر المُحلِّل، ويبدأ التنزيل في وقت أقرب.
<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>
تحميل الموارد التابعة لجهات خارجية ببطء
تكون جميع الموارد المتوفّرة في الجزء السفلي غير المرئي من الصفحة مناسبة تمامًا للتحميل الكسول.
يتضمّن نموذج التطبيق فيديو على YouTube مضمّنًا في إطار iframe. لمعرفة عدد الطلبات التي تقدّمها الصفحة وتلك التي تأتي من إطار iframe المضمّن في YouTube، اتّبِع الخطوات التالية:
- لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط على ملء الشاشة .
- اضغط على "Control+Shift+J" (أو "Command+Option+J" على نظام التشغيل Mac) لفتح "أدوات مطوري البرامج".
- انقر على علامة التبويب الشبكة.
- ضَع علامة في مربّع الاختيار إيقاف ذاكرة التخزين المؤقت.
- اختَر شبكة الجيل الثالث السريعة في القائمة المنسدلة تقييد السرعة.
- إعادة تحميل الصفحة
تكشف لوحة الشبكة أنّ الصفحة قدّمت 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.