تحسين التفاعل مع سرعة عرض المحتوى على الصفحة التالية

تعرَّف على كيفية تحسين مدى استجابة الصفحة لتفاعلات المستخدم مع موقعك الإلكتروني.

مدى استجابة الصفحة لتفاعلات المستخدم (INP) هو مقياس "مؤشرات أداء الويب الأساسية" الثابت يقيّم مدى استجابة الصفحة بشكل عام لتفاعلات المستخدمين من خلال رصد وقت الاستجابة لجميع التفاعلات المؤهِّلة التي تحدث طوال فترة زيارة المستخدم للصفحة. وتكون قيمة INP النهائية هي أطول تفاعل تم ملاحظته (يتم أحيانًا تجاهل القيم المتطرفة).

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

تبلغ قيم INP الجيدة 200 ملّي ثانية أو أقل، والقيم الضعيفة تزيد عن 500 ملّي ثانية، وأي قيمة تحدث بينهما بحاجة إلى تحسين.

اعتمادًا على موقع الويب، قد يكون هناك القليل من التفاعلات أو قد لا تكون هناك تفاعلات - مثل صفحات تحتوي في الغالب على نصوص وصور تحتوي على عدد قليل من العناصر التفاعلية أو بدون عناصر تفاعلية. أو، في حالة مواقع الويب مثل برامج تحرير النصوص أو الألعاب، قد يكون هناك المئات وحتى الآلاف من التفاعلات. وفي كلتا الحالتين، تكون تجربة المستخدم عرضة للخطر عندما يكون معدّل INP مرتفعًا.

إنّ تحسين INP يستغرق وقتًا وجهدًا، لكنّ المكافأة تحسّن تجربة المستخدم. في هذا الدليل، سنستكشف مسارًا لتحسين INP.

معرفة أسباب ضعف "مدى استجابة الصفحة لتفاعلات المستخدم" (INP)

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

العثور على التفاعلات البطيئة في الميدان

من المفترض أن تبدأ رحلتك في تحسين INP من خلال البيانات الفعلية. وفي أفضل حالاتها، لن تمنحك البيانات الميدانية التي يوفّرها موفّر خدمة "تتبُّع المستخدم الفعلي" (RUM) قيمة INP للصفحة فحسب، بل ستمنحك أيضًا بيانات سياقية تسلّط الضوء على التفاعل المحدَّد المسؤول عن قيمة INP نفسها، سواء حدث التفاعل أثناء تحميل الصفحة أو بعده، ونوع التفاعل (النقر أو الضغط على مفتاح أو النقر) ومعلومات أخرى قيّمة.

إذا لم تكن تعتمد على موفر RUM للحصول على بيانات الحقول، دليل بيانات حقل INP يقدم نصائح باستخدام تقرير تجربة مستخدم Chrome (CrUX) من خلال "إحصاءات PageSpeed " للمساعدة في سد الثغرات. تقرير تجربة المستخدم (CrUX) هو مجموعة البيانات الرسمية لبرنامج "مؤشرات أداء الويب الأساسية"، ويقدّم ملخّصًا شاملاً للمقاييس في ملايين المواقع الإلكترونية، بما في ذلك مقياس INP. ومع ذلك، لا توفر CrUX غالبًا البيانات السياقية التي تحصل عليها من مزود RUM لمساعدتك في تحليل المشكلات. ولهذا السبب، ما زلنا نقترح أن تستخدم المواقع الإلكترونية مزود RUM إن أمكن، أو تنفيذ حل RUM الخاص بها لاستكمال ما هو متاح في CrUX.

تشخيص التفاعلات البطيئة في التمرين المعملي

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

تحسين التفاعلات

فبعد تحديد تفاعل بطيء وإمكانية إعادة إنتاجه يدويًا في التمرين المعملي، تتمثل الخطوة التالية في تحسينه. يمكن تقسيم التفاعلات إلى ثلاث مراحل:

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

مجموع هذه المراحل الثلاث هو إجمالي وقت استجابة التفاعل. تساهم كل مرحلة من مراحل التفاعل في بعض الوقت في إجمالي وقت استجابة التفاعل، لذا من المهم معرفة كيفية تحسين كل جزء من التفاعل بحيث يعمل لأقل وقت ممكن.

تحديد تأخير الإدخال وتقليله

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

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

العلاقة بين تقييم النص والمهام الطويلة أثناء بدء التشغيل

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

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

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

تحسين عمليات معاودة الاتصال بالأحداث

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

الانتقال إلى سلسلة التعليمات الرئيسية في أغلب الأحيان

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

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

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

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

النتيجة للسماح بعرض العمل في وقت أقرب

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

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

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

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

قد يبدو الكود المناسب لذلك على النحو التالي:

textBox.addEventListener('input', (inputEvent) => {
  // Update the UI immediately, so the changes the user made
  // are visible as soon as the next frame is presented.
  updateTextBox(inputEvent);

  // Use `setTimeout` to defer all other work until at least the next
  // frame by queuing a task in a `requestAnimationFrame()` callback.
  requestAnimationFrame(() => {
    setTimeout(() => {
      const text = textBox.textContent;
      updateWordCount(text);
      checkSpelling(text);
      saveChanges(text);
    }, 0);
  });
});

يوضِّح العرض المرئي التالي أنّ تأجيل أيّ تعديلات غير مهمّة إلى ما بعد الإطار التالي يمكن أن يقلّل من مدة المعالجة، وبالتالي من وقت استجابة التفاعل بشكلٍ عام.

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

على الرغم من أنّ استخدام setTimeout() في استدعاء requestAnimationFrame() في مثال الرمز السابق هو أسلوب سري إلى حد ما، فإنّها طريقة فعّالة تعمل في جميع المتصفحات لضمان عدم حظر الرمز غير المُهم الإطار التالي.

تجنُّب تكديس التخطيط

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

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

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

تقليل تأخير العرض التقديمي

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

تقليل حجم DOM

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

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

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

استخدِم content-visibility لعرض العناصر خارج الشاشة بشكل كسول

إحدى الطرق التي يمكنك من خلالها تحديد مقدار عمل العرض أثناء تحميل الصفحة وعمل العرض استجابةً لتفاعلات المستخدمين هي الاعتماد على سمة content-visibility في CSS، ما يؤدي بفعالية إلى عرض عناصر العرض الكسول عند الاقتراب من إطار العرض. على الرغم من أنّ استخدام content-visibility قد يحتاج إلى بعض التدريبات بشكل فعّال، من الجدير التحقّق ممّا إذا كانت النتيجة أقل من وقت العرض، ما قد يحسّن INP لصفحتك.

الانتباه إلى تكاليف الأداء عند عرض HTML باستخدام JavaScript

في حال كان هناك HTML، يكون هناك تحليل HTML، وبعد انتهاء المتصفّح من تحليل HTML إلى نموذج DOM، يجب أن يطبّق الأنماط عليه، ويجري حسابات التنسيق، ثمّ يعرض ذلك التنسيق. وهذه تكلفة لا مفرّ منها، ولكن كيفية عرض HTML مهمة.

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

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

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

الخلاصة

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

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

صورة رئيسية من Unpush، بقلم "ديفيد بيسنوي"، وتم تعديلها وفقًا لترخيص إلغاء البداية.