درس تطبيقي حول الترميز: تحميل مواد العرض المهمة مسبقًا لتحسين سرعة التحميل

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

لقطة شاشة التطبيق

قياس

عليك أولاً قياس مستوى أداء الموقع الإلكتروني قبل إضافة أي تحسينات.

  • لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق، ثم اضغط على ملء الشاشة ملء الشاشة.

إجراء تدقيق الأداء في Lighthouse (Lighthouse > الخيارات > الأداء) على النسخة المباشرة من أداة Glitch (راجِع أيضًا اكتشاف فرص الأداء باستخدام Lighthouse).

تعرض أداة Lighthouse عملية التدقيق التالية غير الناجحة لمورد تم جلبه في وقت متأخر:

أداة Lighthouse: مراجعة طلبات التحميل المُسبق لطلبات المفاتيح
  • اضغط على "Control+Shift+J" (أو "Command+Option+J" على نظام التشغيل Mac) لفتح "أدوات مطوّري البرامج".
  • انقر على علامة التبويب الشبكة.
لوحة شبكة تتضمّن مرجعًا تم اكتشافه متأخرًا

لا يتم جلب ملف main.css من خلال عنصر الرابط (<link>) الموضوع في مستند HTML، إلا أنّ ملف JavaScript منفصل fetch-css.js يرفق عنصر الرابط إلى نموذج العناصر في المستند (DOM) بعد حدث window.onLoad. وهذا يعني أنّه لا يتم جلب الملف إلا بعد أن ينتهي المتصفّح من تحليل ملف JS وتنفيذه. وبالمثل، لا يتم جلب خط الويب (K2D.woff2) المحدّد ضمن main.css إلا بعد الانتهاء من تنزيل ملف CSS.

تمثل سلسلة الطلبات المهمة ترتيب الموارد التي يتم تحديد أولوية الموارد وجلبها من خلال المتصفِّح. بالنسبة لصفحة الويب هذه، تبدو حاليًا كما يلي:

├─┬ / (initial HTML file)
  └── fetch-css.js
    └── main.css
      └── K2D.woff2

نظرًا لأن ملف CSS موجود في المستوى الثالث من سلسلة الطلبات، فقد صنفته أداة Lighthouse على أنه مورد تم اكتشافه مؤخرًا.

تحميل الموارد المهمة مسبقًا

الملف main.css هو مادة عرض مهمة مطلوبة فورًا فور تحميل الصفحة. بالنسبة إلى الملفات المهمة مثل هذا المورد التي يتم جلبها في وقت متأخر في تطبيقك، استخدِم علامة التحميل المسبق للرابط لإبلاغ المتصفح بتنزيله بشكل أسرع عن طريق إضافة عنصر رابط إلى رأس المستند.

إضافة علامة تحميل مسبق لهذا التطبيق:

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
</head>

تُستخدَم السمة as لتحديد نوع المورد الذي يتم جلبه، وتُستخدم السمة as="style" لتحميل ملفات ورقة الأنماط مسبقًا.

أعِد تحميل التطبيق وألقِ نظرة على لوحة الشبكة في "أدوات مطوري البرامج".

لوحة شبكة تتضمّن مرجعًا تم تحميله مسبقًا

لاحِظ كيف يجلب المتصفّح ملف CSS قبل انتهاء تحليل JavaScript المسؤول عن جلبه. باستخدام التحميل المُسبق، يعرف المتصفّح إجراء عملية جلب استباقية للموارد بافتراض أنّه أمر بالغ الأهمية لصفحة الويب.

إذا لم يتم استخدام التحميل المسبق بشكل صحيح، يمكن أن يضر بالأداء من خلال تقديم طلبات غير ضرورية للموارد التي لا يتم استخدامها. في هذا التطبيق، يكون details.css ملف CSS آخر في جذر المشروع، ولكن يتم استخدامه في ملف /details route منفصل. لعرض مثال يوضِّح طريقة استخدام التحميل المُسبق بشكل غير صحيح، أضِف تلميحًا بشأن التحميل المُسبق لهذا المورد أيضًا.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

أعِد تحميل التطبيق وألقِ نظرة على لوحة الشبكة. يتم تقديم طلب لاسترداد details.css على الرغم من عدم استخدامه في صفحة الويب.

لوحة الشبكة تتضمن تحميل مسبق غير ضروري

يعرض Chrome تحذيرًا في لوحة وحدة التحكم عند عدم استخدام الصفحة لمورد تم تحميله مسبقًا خلال بضع ثوانٍ بعد تحميله.

تحذير بشأن التحميل المُسبق في وحدة التحكّم

استخدِم هذا التحذير كمؤشر لتحديد ما إذا كانت لديك أي موارد تم تحميلها مسبقًا لا تستخدمها صفحتك على الويب على الفور. يمكنك الآن إزالة رابط التحميل المسبق غير الضروري لهذه الصفحة.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

للحصول على قائمة بجميع أنواع الموارد التي يمكن جلبها مع القيم الصحيحة التي يجب استخدامها للسمة as، يمكنك الاطّلاع على مقالة MDN عن "التحميل المُسبق".

الجلب المسبق للموارد المستقبلية

الجلب المسبق هو تلميح آخر في المتصفح يمكن استخدامه لتقديم طلب للحصول على مادة عرض مستخدَمة في مسار تنقّل مختلف ولكن تكون أولوية أقل منها مقارنةً بمواد العرض المهمة الأخرى اللازمة للصفحة الحالية.

في هذا الموقع الإلكتروني، ينقلك النقر على الصورة إلى مسار details/ منفصل.

مسار عرض التفاصيل

ملف CSS المنفصل details.css يحتوي على جميع الأنماط اللازمة لهذه الصفحة البسيطة. أضِف عنصر رابط إلى index.html لجلب هذا المورد مُسبقًا.

<head>
  <!-- ... -->
  <link rel="prefetch" href="details.css">
</head>

لفهم كيف يؤدي ذلك إلى ظهور طلب للملف، افتح لوحة الشبكة في "أدوات مطوري البرامج" وأزِل العلامة من المربّع إيقاف ذاكرة التخزين المؤقت.

إيقاف ذاكرة التخزين المؤقت في &quot;أدوات مطوري البرامج في Chrome&quot;

أعِد تحميل التطبيق ولاحظ كيف يتم تقديم طلب ذي أولوية منخفضة للغاية لـ details.css بعد أن يتم استرجاع جميع الملفات الأخرى.

لوحة شبكة تتضمّن موردًا تم جلبه مسبقًا

بعد فتح أدوات مطوّري البرامج، انقر على الصورة في الموقع الإلكتروني للانتقال إلى صفحة details. بما أنّه يتم استخدام عنصر رابط في details.html لاسترجاع details.css، يتم تقديم طلب للمورد على النحو المتوقّع.

طلبات الشبكة على صفحة التفاصيل

انقر على طلب شبكة "details.css" في "أدوات مطوري البرامج" للاطّلاع على تفاصيله. ستلاحظ أنّه يتم استرداد الملف من ذاكرة التخزين المؤقت على القرص في المتصفّح.

تم استرجاع طلب التفاصيل من ذاكرة التخزين المؤقت على القرص

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

التحميل المُسبق والجلب المسبق باستخدام حزمة الويب

تستكشف المشاركة تقليل حمولات JavaScript من خلال تقسيم الرمز استخدام عمليات الاستيراد الديناميكية لتقسيم حزمة إلى أجزاء متعدّدة. ويمكن توضيح ذلك من خلال تطبيق بسيط يستورد وحدة بشكل ديناميكي من Lodash عند إرسال نموذج.

تطبيق &quot;Magic Sorter&quot; (أداة الترتيب السحرية) يوضّح طريقة تقسيم الرموز

يمكنك الوصول إلى تأثير Glitch لهذا التطبيق من هنا.

تكون مجموعة الرموز التالية، والموجودة في src/index.js,، مسؤولة عن الاستيراد الديناميكي للطريقة عند النقر على الزر.

form.addEventListener("submit", e => {
  e.preventDefault()
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

يؤدي تقسيم الحزمة إلى تحسين أوقات تحميل الصفحات عن طريق تقليل حجمها الأولي. يوفر الإصدار 4.6.0 من حزمة الويب دعمًا للتحميل المسبق أو الجلب المسبق للمقاطع التي يتم استيرادها ديناميكيًا. باستخدام هذا التطبيق كمثال، يمكن جلب طريقة lodash مُسبقًا في وقت عدم نشاط المتصفّح، وعندما يضغط المستخدم على الزر، لن يحدث أي تأخير في جلب الموارد.

استخدِم مَعلمة التعليق webpackPrefetch المحدّدة في عملية استيراد ديناميكية لجلب مقطع معيّن مسبقًا. إليك كيف سيبدو التطبيق مع هذا التطبيق بالتحديد.

form.addEventListener("submit", e => {
  e.preventDefault()
  import(/* webpackPrefetch: true */ 'lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

بعد إعادة تحميل التطبيق، تُدخل حزمة الويب علامة جلب مُسبق للمورّد في رأس المستند. ويمكن رؤية ذلك في لوحة العناصر في "أدوات مطوري البرامج".

لوحة العناصر مع علامة جلب مسبق

عند ملاحظة الطلبات في لوحة الشبكة، تُظهر أيضًا أنّه يتم جلب هذا المقطع بأولوية منخفضة بعد طلب جميع الموارد الأخرى.

لوحة الشبكة تتضمن طلبًا تم جلبه مسبقًا

على الرغم من أنّ ميزة "الجلب المُسبَق" تبدو أكثر منطقيةً لحالة الاستخدام هذه، توفّر حزمة الويب أيضًا إمكانية التحميل المُسبق للأجزاء التي يتم استيرادها ديناميكيًا.

import(/* webpackPreload: true */ 'module')

الخلاصة

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

خلاصة القول:

  • استخدِم ميزة التحميل المسبق للموارد التي يتم اكتشافها متأخرًا ولكنها ضرورية في الصفحة الحالية.
  • استخدِم ميزة الجلب المُسبَق للموارد المطلوبة لمسار التنقُّل أو إجراء المستخدم المستقبلي.

لا تتيح بعض المتصفحات حاليًا استخدام كل من التحميل المُسبق والجلب المسبق. وهذا يعني أنّه قد لا يلاحظ بعض مستخدمي التطبيق تحسينات في الأداء.

إذا كنت ترغب في الحصول على مزيد من المعلومات حول جوانب معينة لكيفية تأثير التحميل المسبق والجلب المسبق على صفحة الويب، يُرجى الرجوع إلى المقالات التالية: