آلية إنشاء "إحصاءات الأداء" والغرض من ذلك

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

ALT_TEXT_HERE

لماذا أنشأنا لوحة تحكّم أخرى؟

(إذا لم يسبق لك مشاهدة هذا الفيديو، لقد نشرنا فيديو حول سبب إنشاء لوحة "إحصاءات الأداء" وكيفية الحصول على إحصاءات قابلة للتنفيذ حول أداء موقعك الإلكتروني باستخدامها).

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

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

رابط الملاحظات والآراء في اللوحة

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

كيف أنشأنا ميزة "إحصاءات الأداء"؟

كما هو الحال مع بقية أدوات DevTools، أنشأنا "إحصاءات الأداء" باستخدام TypeScript واستخدمنا مكوّنات الويب المستندة إلى lit-html لإنشاء واجهة المستخدم. تختلف "إحصاءات الأداء" في أنّ واجهة المستخدم الأساسية هي عنصر canvas بلغة HTML، ويتم رسم المخطط الزمني على لوحة الرسم هذه. يأتي الكثير من التعقيد من إدارة لوحة العرض هذه: ليس فقط رسم التفاصيل الصحيحة في المكان المناسب، ولكن أيضًا إدارة أحداث الماوس (على سبيل المثال: أين نقر المستخدم على لوحة العرض؟ هل نقروا على حدث رسمناه؟) والتأكّد من إعادة عرض لوحة العرض بشكل فعّال.

مقاطع صوتية متعدّدة على لوحة واحدة

بالنسبة إلى موقع إلكتروني معيّن، هناك مسارات متعدّدة نريد عرضها، ويمثّل كل مسار فئة مختلفة من البيانات. على سبيل المثال، ستعرض لوحة "الإحصاءات" ثلاث قنوات صوتية تلقائيًا:

ومع استمرارنا في إضافة ميزات إلى اللوحة، نتوقّع أن تتم إضافة المزيد من الأغاني.

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

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

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

canvasContext.beginPath();
canvasContext.rect(
    trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();

لم نرد أيضًا أن يعرف كل مقطع موقعه عموديًا: يجب أن يتم عرض كل مقطع كما لو كان يتم عرضه في (0, 0)، ولدينا مكوّن أعلى مستوى (نسميه TrackManager) لإدارة موضع المقطع الإجمالي. يمكن إجراء ذلك باستخدام translate، الذي ينقل لوحة الرسم بمقدار موضع (س، ص) محدّد. على سبيل المثال:

canvasContext.translate(0, 10); // Translate by 10px in the y direction
canvasContext.rect(0, 0, 10, 10); // draw a rectangle at (0, 0) that’s 10px high and wide

على الرغم من أنّ rect رمز الإعداد 0, 0 يمثّل الموضع، سيؤدي الترجمة الإجمالية المطبّقة إلى عرض المستطيل في 0, 10. يسمح لنا ذلك بالعمل على أساس المسار كما لو كنا نعرض المحتوى عند النقطة (0, 0)، ويسمح لمدير المسار بترجمة المحتوى أثناء عرضه لكل مسار لضمان عرض كل مسار بشكل صحيح أسفل المسار السابق.

لوحات عرض خارج الشاشة للمقاطع والأغاني الرائجة

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

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

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

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

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

تحليل شامل لعملية تحليل التتبُّع

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

تحليل ملف التتبُّع واستخراج البيانات المطلوبة عرض مجموعة من المقاطع الصوتية

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

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

اختبار لقطات الشاشة لواجهة مستخدم لوحة العرض

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

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

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

الخاتمة

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

لمزيد من المعلومات عن لوحة "إحصاءات الأداء"، يمكنك الاطّلاع على إحصاءات الأداء: الحصول على إحصاءات قابلة للاستخدام حول أداء موقعك الإلكتروني.

تنزيل قنوات المعاينة

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

التواصل مع فريق Chrome DevTools

استخدِم الخيارات التالية لمناقشة الميزات الجديدة أو التحديثات أو أي شيء آخر متعلّق بـ "أدوات مطوّري البرامج".