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

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

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

القياس

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

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

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

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

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

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

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

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

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

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

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

أضِف علامة التحميل المُسبَق لهذا التطبيق:

<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 على الرغم من أنّ صفحة الويب لا تستخدمه.

لوحة &quot;الشبكة&quot; مع التحميل المُسبَق غير الضروري

يعرض 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 بعد جلب جميع الملفات الأخرى.

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

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

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

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

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

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

التحميل المُسبَق والجلب المُسبَق باستخدام webpack

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

تطبيق Magic Sorter الذي يوضّح تقسيم الرموز

يمكنك الوصول إلى تطبيق 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 من webpack إمكانية التحميل المسبق أو الجلب المسبق للأجزاء التي يتم استيرادها ديناميكيًا. باستخدام هذا التطبيق كمثال، يمكن جلب البيانات مسبقًا لطريقة lodash أثناء عدم نشاط المتصفّح، وعندما ينقر المستخدم على الزر، لن يكون هناك أي تأخير في جلب المورد.

استخدِم مَعلمة التعليق webpackPrefetch المحدّدة ضمن عملية استيراد ديناميكية لجلب جزء معيّن مسبقًا. في ما يلي الشكل الذي ستظهر به مع هذا التطبيق تحديدًا.

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

بعد إعادة تحميل التطبيق، يدرج webpack علامة prefetch للمورد في رأس المستند. يمكن الاطّلاع على ذلك في لوحة العناصر في "أدوات مطوّري البرامج".

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

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

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

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

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

الخاتمة

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

باختصار:

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

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

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