تحسين "مهلة الاستجابة لأوّل إدخال"

كيفية الاستجابة بشكل أسرع لتفاعلات المستخدمين

نقرتُ على ولكن لم يحدث شيء. لماذا لا يمكنني التفاعل مع هذه الصفحة؟ 😢

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

مهلة الاستجابة الأولى (FID) هو مقياس في مؤشرات أداء الويب الأساسية يلتقط أول انطباع لدى المستخدم عن مدى تفاعل الموقع الإلكتروني واستجابته. وهو يقيس الوقت منذ تفاعل المستخدم مع الصفحة لأول مرة إلى الوقت الذي يكون فيه المتصفّح قادرًا على الاستجابة لهذا التفاعل. إنّ مقياس FID هو مقياس ميداني ولا يمكن محاكته في بيئة معملية. إنّ تفاعل المستخدم حقيقيًا مطلوب لقياس التأخير في الاستجابة.

تبلغ قيم الحصة الجيدة 2.5 ثانية، والقيم الضعيفة أكبر من 4.0 ثانية وأي قيمة بينهما بحاجة إلى تحسين.

للمساعدة في توقّع مقياس FID في الدرس التطبيقي، ننصحك بإجراء إجمالي وقت الحظر (TBT). وهي تقيس أشياء مختلفة، لكن التحسينات في TBT عادةً ما تتوافق مع التحسينات في FID.

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

التنفيذ الكثيف لJavaScript

لا يمكن للمتصفّح الاستجابة إلى معظم إدخالات المستخدمين أثناء تنفيذ JavaScript في سلسلة التعليمات الرئيسية. بمعنى آخر، لا يمكن للمتصفح الاستجابة لتفاعلات المستخدم عندما يكون مؤشر الترابط الرئيسي مشغولاً. لتحسين ذلك:

تقسيم المهام الطويلة

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

المهام الطويلة هي فترات تنفيذ JavaScript قد يجد فيها المستخدمون عدم استجابة واجهة المستخدم. يمكن تصنيف أي رمز برمجي يحظر سلسلة التعليمات الرئيسية لمدة 50 ملي ثانية أو أكثر على أنّه "مهمة طويلة". تُعد المهام الطويلة علامة على وجود ثغرة JavaScript محتملة (تحميل وتنفيذ أكثر مما قد يحتاجه المستخدم في الوقت الحالي). ويمكن أن يؤدي تقسيم المهام الطويلة إلى تقليل تأخّر إدخال البيانات على موقعك الإلكتروني.

المهام الطويلة في "أدوات مطوري البرامج في Chrome"
يعرض "أدوات مطوري البرامج في Chrome" المهام الطويلة في لوحة الأداء

من المفترض أن يتحسّن مقياس FID بشكل ملحوظ عند تطبيق أفضل الممارسات، مثل تقسيم الرموز البرمجية وتقسيم المهام الطويلة. على الرغم من أنّ تحديد TBT ليس مقياسًا ميدانيًا، فهو مفيد للتحقق من مستوى التقدّم نحو تحسين كلّ من "وقت التفاعل" (TTI) وFID (مهلة الاستجابة الأولى).

تحسين صفحتك لتعزيز الاستعداد للتفاعل

هناك عدة أسباب شائعة لضعف درجات FID وTBT في تطبيقات الويب التي تعتمد بشكل كبير على JavaScript:

يمكن أن يؤدي تنفيذ النص البرمجي للطرف الأول إلى تأخير جاهزية التفاعل.

  • قد يؤدي تباطؤ حجم JavaScript وأوقات التنفيذ الثقيلة والتقسيم غير الفعال إلى إبطاء معدل استجابة الصفحة لإدخال المستخدم وتأثير FID وTBT وTI. يمكن أن يساعد التحميل التدريجي للتعليمة البرمجية والميزات في نشر هذا التمرين وتحسين الاستعداد للتفاعل.
  • قد تبدو التطبيقات المعروضة من جهة الخادم وكأنّها يتم عرض وحدات بكسل على الشاشة بسرعة، ولكن عليك الانتباه إلى أنّ تفاعلات المستخدمين محظورة بسبب عمليات تنفيذ النصوص البرمجية الكبيرة (على سبيل المثال، إعادة تحويل البيانات إلى وحدات معالجة الأحداث عبر الشبكة). قد يستغرق ذلك عدة مئات من المللي ثانية، أو قد يستغرق أحيانًا ثوانٍ، إذا كان يتم تقسيم الرمز المستند إلى المسار. يمكنك التفكير في تحويل مزيد من المنطق من جهة الخادم أو إنشاء المزيد من المحتوى بشكل ثابت أثناء وقت الإنشاء.

في ما يلي نتائج يُحدَّد لاحقًا قبل تحسين تحميل النص البرمجي للطرف الأول لأحد التطبيقات وبعده. ومن خلال نقل تحميل (وتنفيذ) النص البرمجي المكلف لمكوِّن غير أساسي خارج المسار الحرج، تمكّن المستخدمون من التفاعل مع الصفحة بسرعة أكبر.

تحسينات في نتيجة TBT في Lighthouse بعد تحسين النص البرمجي للطرف الأول

يمكن أن يؤثر جلب البيانات في العديد من جوانب الاستعداد للتفاعل

  • قد يؤثر انتظار عمليات جلب متتالية (مثل JavaScript واسترجاع البيانات للمكوّنات) في وقت استجابة التفاعل. استهدف تقليل الاعتماد على عمليات جلب البيانات المتتالية.
  • يمكن أن تؤدي مخزن البيانات المضمّنة الكبيرة إلى زيادة وقت تحليل HTML والتأثير على مقاييس الرسم والتفاعل. استهدف تقليل مقدار البيانات التي يجب معالجتها لاحقًا من جانب العميل.

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

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

استخدام عامل على الويب

سلسلة التعليمات الرئيسية المحظورة هي أحد الأسباب الرئيسية لتأخير عملية الإدخال. يتيح العاملون على الويب تشغيل JavaScript على سلسلة محادثات في الخلفية. يمكن أن يؤدي نقل العمليات التي لا تعتمد على واجهة المستخدم إلى سلسلة تعليمات منفصلة للعمال إلى تقليل وقت حظر سلسلة التعليمات الرئيسية وبالتالي تحسين مقياس FID.

يمكنك استخدام المكتبات التالية لتسهيل استخدام عمال الويب على موقعك الإلكتروني:

  • Comlink: مكتبة مساعِدة تلخّص postMessage وتسهّل استخدامها
  • Workway: مصدِّر مشغّلات ويب للأغراض العامة
  • العمل: نقل وحدة إلى عامل على الويب

تقليل وقت تنفيذ JavaScript

إنّ الحدّ من مقدار لغة JavaScript على صفحتك يؤدي إلى تقليل الوقت الذي يحتاجه المتصفّح لتنفيذ رمز JavaScript. ويؤدي ذلك إلى تسريع سرعة بدء المتصفّح في الاستجابة لأي تفاعلات المستخدم.

لتقليل مقدار محتوى JavaScript الذي يتم تنفيذه على صفحتك:

  • تأجيل محتوى JavaScript غير المستخدَم
  • تقليل رموز polyfill غير المستخدَمة

تأجيل محتوى JavaScript غير المستخدَم

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

يمكنك الاطّلاع على علامة تبويب التغطية في "أدوات مطوري البرامج في Chrome" لمعرفة مقدار JavaScript الذي لا يتم استخدامه في صفحتك على الويب.

علامة التبويب "التغطية"

للحدّ من استخدام محتوى JavaScript غير المستخدَم، يُرجى اتّباع الخطوات التالية:

  • قسّم التعليمة البرمجية الحزمة إلى أجزاء متعددة
  • تأجيل أي محتوى JavaScript غير مهم، بما في ذلك النصوص البرمجية التابعة لجهات خارجية، باستخدام async أو defer

تقسيم الرمز هو مفهوم تقسيم حزمة JavaScript واحدة كبيرة إلى أجزاء أصغر يمكن تحميلها بشروط (المعروفة أيضًا باسم "التحميل الكسول"). تتوافق معظم المتصفحات الأحدث مع بنية الاستيراد الديناميكية، ما يسمح بجلب الوحدات عند الطلب:

import('module.js').then((module) => {
  // Do something with the module.
});

سيؤدي استيراد لغة JavaScript ديناميكيًا في تفاعلات بعض المستخدمين (مثل تغيير مسار أو عرض نمط) إلى التأكّد من أنّ الرمز الذي لم يتم استخدامه في التحميل الأولي للصفحة لا يتم جلبه إلا عند الحاجة.

إلى جانب الدعم العام للمتصفّح، يمكن استخدام بنية الاستيراد الديناميكية في العديد من أنظمة التصميم المختلفة.

  • إذا كنت تستخدم حزمة الويب أو الدمج أو Parcel كحزمة وحدات، استفِد من إتاحة الاستيراد الديناميكي.
  • إنّ أطر العمل من جهة العميل، مثل React وAngular وVue، توفّران تجريدات لتسهيل عملية التحميل الكسول على مستوى المكوّنات.

بصرف النظر عن تقسيم الرموز، استخدم دائمًا غير متزامن أو مؤجل للنصوص البرمجية غير الضرورية لمحتوى المسار الحرج أو محتوى الجزء المرئي من الصفحة.

<script defer src="…"></script>
<script async src="…"></script>

يجب تلقائيًا تحميل جميع النصوص البرمجية التابعة لجهات خارجية باستخدام defer أو async، ما لم يكن هناك سبب محدّد لعدم حدوث ذلك.

تقليل رموز polyfill غير المستخدَمة

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

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

لتحسين استخدام رموز polyfill على موقعك الإلكتروني:

  • إذا كنت تستخدم Babel كبرنامج للترجمة النصية، استخدِم @babel/preset-env لتضمين رموز polyfill اللازمة للمتصفّحات التي تخطّط لاستهدافها فقط. بالنسبة إلى الإصدار 7.9 من Babel، يمكنك تفعيل خيار bugfixes لتقليل أيّ رموز polyfill غير ضرورية.
  • استخدِم نمط الوحدة/nounit لتقديم حزمتين منفصلتين (تتيح ميزة @babel/preset-env أيضًا استخدام هذا النمط من خلال target.esmodules)

    <script type="module" src="modern.js"></script>
    <script nomodule src="legacy.js" defer></script>
    

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

أدوات المطوّرين

يتوفّر عدد من الأدوات لقياس FID وتصحيح الأخطاء فيه:

  • لا يتوافق Lighthouse 6.0 مع مقياس FID لأنّه مقياس حقل. ومع ذلك، يمكن استخدام إجمالي وقت الحظر (TBT) كخادم وكيل. إنّ التحسينات التي تساعد في تحسين التتبع في الوقت الفعلي ستعمل أيضًا على تحسين مقياس FID على مستوى المجال.

    الإصدار 6.0 من Lighthouse

  • يوفّر تقرير تجربة المستخدم في Chrome قيم FID الفعلية المجمَّعة على مستوى المصدر

نشكر "فيليب والتون" و"كايس باسك" و"إيليا غريغوريك" و"آني سوليفان" على مراجعاتهم.