توضّح هذه الدراسة الحالة سير العمل المفصّل لتحديد الأخطاء وحلّها وتحسين ملف INP
في React الذي تستخدمه شركة Trendyol من خلال الاستفادة من أدوات Google، مثل إحصاءات سرعة التحميل (PSI) في PageSpeed وChrome DevTools وscheduler.yield
API.
إنّ صفحة بيانات المنتج (PLP) وصفحة تفاصيل المنتج (PDP) هما مكوّنان رئيسيان لأي موقع إلكتروني للتجارة الإلكترونية. غالبًا ما تأتي زيارات التجارة الإلكترونية من صفحات بيانات المنتجات، سواء من خلال حملات البريد الإلكتروني أو وسائل التواصل الاجتماعي أو الإعلانات. نتيجةً لذلك، من المهم التأكّد من أنّ تجربة PLP مصمّمة بعناية لتقليل الوقت الذي يستغرقه إتمام عملية الشراء. إنّ منح الأولوية لجودة تجربة المستخدم أمر ضروري لتحقيق النجاح. لقد كشفت الإصدارات البحثية، مثل Milliseconds Make Millions، عن التأثير الكبير لأداء الويب في استعداد المستهلكين لإنفاق الأموال والتفاعل مع العلامات التجارية على الإنترنت.
Trendyol هي منصة للتجارة الإلكترونية تضمّ حوالي 30 مليون عميل و 240,000 بائع، ما دفعنا إلى أن نصبح أوّل نشاط تجاري في تركيا بقيمة تزيد عن 10 مليارات دولار أمريكي، وإحدى أهم منصات التجارة الإلكترونية في العالم.
لتحقيق هدفها المتمثل في تقديم أفضل تجربة ممكنة للمستخدم على نطاق واسع، مع الحفاظ على مرونة المحتوى والعمل باستخدام إصدار قديم من React، ركزت Trendyol على مدى استجابة الصفحة لتفاعلات المستخدم (INP) كمقياس رئيسي لتحسينه. توضّح هذه الدراسة الحالة رحلة Trendyol في تحسين مقياس INP في صفحة المنتج في خدمة مقارنة الأسعار (PLP)، ما أدّى إلى انخفاض بنسبة% 50 في مقياس INP وزيادة بنسبة% 1 في مقياس النشاط التجاري لنتائج البحث .
عملية التحقيق في طلبات الحصول على إذن بالوصول إلى البيانات (INP) في Trendyol
يقيس مقياس INP استجابة الموقع الإلكتروني للبيانات التي يُدخلها المستخدم. يشير مقياس INP الجيد إلى أنّ المتصفّح قادر على الاستجابة سريعًا وموثوقًا لجميع بيانات المستخدمين وإعادة رسم الصفحة، ما يشكّل مكوّنًا أساسيًا لتجربة مستخدم جيدة.
بدأت رحلة Trendyol لتحسين مقياس INP في قائمة المنتجات في صفحة البحث من خلال إجراء تحليل شامل لمحاولة تحسين تجربة المستخدم قبل إجراء أي تحسينات. استنادًا إلى تقرير PSI، كانت قيمة INP لتجربة المستخدم الفعلية في PLP هي 963 ملي ثانية على الأجهزة الجوّالة، كما هو موضّح في الشكل التالي.
لضمان سرعة الاستجابة الجيدة، يجب أن يهدف مالكو المواقع الإلكترونية إلى الحصول على قيمة INP أدنى من أو مساوية 200 ملي ثانية، ما يعني أنّ قيمة INP لموقع Trendyol كانت في ذلك الوقت ضمن النطاق "الضعيف".
لحسن الحظ، يوفّر PSI كلاً من بيانات الاستخدام الفعلي للصفحات المضمّنة في تقرير تجرب مستخدمي Chrome (CrUX) وبيانات تشخيص مفصّلة في المختبر. عند الاطّلاع على ملفّات قاعدة بيانات
الاختبار، أشارت تدقيق وقت تنفيذ JavaScript في Lighthouse إلى أنّ ملف برمجي
search-result-v2
كان يشغل السلسلة الرئيسية لفترة أطول من ملفات برمجي
أخرى في الصفحة.
لتحديد نقاط الأداء المنخفضة في الواقع، استخدمنا لوحة الأداء في Chrome DevTools لتحديد المشاكل وحلّها في تجربة PLP وتحديد مصدر المشكلة. من خلال محاكاة أداء الأجهزة الجوّالة مع إبطاء وحدة المعالجة المركزية بمقدار 4 مرات في "أدوات مطوّري برامج Chrome"، تم رصد مهمة تستغرق مدة تتراوح بين 700 و900 ملي ثانية في سلسلة المحادثات الرئيسية. إذا كانت سلسلت المحادثات الرئيسية مشغولة بمهام أخرى لأكثر من 50 مللي ثانية، قد لا تتمكّن من الاستجابة لبيانات المستخدم في الوقت المناسب، ما يؤدي إلى تجربة مستخدم سيئة.
حدثت المهمة الأطول بسبب طلب استدعاء Intersection Observer API في ملف برمجي لنتائج البحث داخل مكوّن React. في هذه المرحلة، بدأنا ننظر في تقسيم هذه المهمة الطويلة إلى أجزاء صغيرة لمنح المتصفّح المزيد من فرص الاستجابة للعمل ذات الأولوية الأعلى، بما في ذلك تفاعلات المستخدمين.
تبيّن أنّ استخدام عملية setState
التي تؤدي إلى إعادة عرض React
داخل ردّ اتصال Intersection Observer يتطلّب تكلفة عالية،
وقد يتسبب ذلك في حدوث مشاكل على الأجهزة المنخفضة الأداء بسبب احتلال السلسلة الرئيسية
لوقت طويل جدًا.
إحدى الطرق التي استخدمها المطوّرون لتقسيم المهام إلى مهام أصغر هي استخدام setTimeout
. لقد استخدمنا هذه التقنية لتأجيل تنفيذ طلب
setState
إلى مهمة منفصلة. على الرغم من أنّ setTimeout
يسمح بتأجيل تنفيذ JavaScript، إلا أنّه لا يقدّم أيّ تحكم في الأولوية. وقد أدّى ذلك
إلى انضمامنا إلى scheduler.yield
الفترة التجريبية للإصدار الأصلي في محاولة لضمان
مواصلة تنفيذ البرنامج النصي بعد التنازل عن سلسلة التعليمات الرئيسية:
/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
if('scheduler' in window && 'yield' in scheduler) {
return await scheduler.yield();
}
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}
/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
entries.forEach(handleIntersection);
const maxNumberOfEntries = Math.max(...this.intersectingEntries);
if (Number.isFinite(maxNumberOfEntries)) {
await this.yieldToMain();
this.setState({ count: maxNumberOfEntries });
}
}, { threshold: 0.5 });
أدّت إضافة طريقة العرض هذه إلى رمز PLP إلى تحسين INP، لأنّه تم تقسيم المَهمّة الطويلة الرئيسية إلى سلسلة من المهام الأصغر حجمًا، ما يسمح بتنفيذ المهام ذات الأولوية الأعلى، مثل تفاعلات المستخدمين وعمليات التقديم اللاحقة، في وقت أقرب مما كان من الممكن.
يُرجى العِلم أنّ Trendyol تستخدم إطار عمل PuzzleJs لتنفيذ بنية واجهة أمامية متناهية الصغر باستخدام React v16.9.0. يمكن تحقيق الأداء نفسه باستخدام React 18، ولكن يتعذّر على Trendyol الترقية في الوقت الحالي لعدة أسباب.
نتائج النشاط التجاري
لقياس تأثير تحسين INP الذي تم تنفيذه، أجرينا اختبار أ/ب لمحاولة معرفة مدى تأثُّر مقاييس النشاط التجاري. بشكل عام، أدّت التغييرات التي أجريناها على صفحة قائمة المنتجات إلى تحسّن كبير، بما في ذلك انخفاض معدّل النقر إلى الشراء بنسبة% 50، بالإضافة إلى زيادة بنسبة %1 في معدّلات النقر من صفحة البيانات إلى صفحة تفاصيل المنتج لكل جلسة مستخدِم. في الشكل التالي، يمكنك الاطّلاع على كيفية تحسين مقياس INP في ملف picuture load time بمرور الوقت:
الخاتمة
إنّ تحسين مقياس INP هو عملية معقّدة ومتكرّرة، ولكن يمكن تسهيلها من خلال سير عمل واضح. تعتمد طريقة بسيطة لتصحيح الأخطاء وتحسين ملف INP الخاص بموقعك الإلكتروني على ما إذا كنت تجمع بياناتك الميدانية. إذا لم يكن الأمر كذلك، يُعدّ PSI وLighthouse نقطة بداية جيدة. بعد تحديد الصفحات التي تتضمّن مشاكل، يمكنك استخدام أدوات مطوّري البرامج للتوغّل أكثر في محاولة إعادة تكرار المشاكل.
إنّ التنازل عن سلسلة المهام الرئيسية من حين لآخر لمنح المتصفّح المزيد من
فرص لتنفيذ المهام الملحّة سيجعل موقعك الإلكتروني أكثر استجابة، ما يضمن
حصول عملائك على تجربة مستخدم أفضل. تسهّل واجهات برمجة التطبيقات الأحدث المخصّصة للجدولة، مثل scheduler.yield()
، هذه المهمة.
نشكر بشكل خاص "جيريمي واغنر" و"باري بولارد" و"حسين جيرديه" من Google وفريق المهندسين في Trendyol على مساهمتهم في هذا العمل.