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

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

ALT_TEXT_HERE

ما هو الغرض من إنشاء لوحة أخرى؟

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

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

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

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

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

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

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

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

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

ونحن نواصل إضافة ميزات إلى اللوحة، لذا نتوقّع إضافة المزيد من القنوات.

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

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

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

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

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

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)، ونطلب من مدير المسار ترجمة المحتوى أثناء عرض كل مسار لضمان عرض كل مسار بشكل صحيح أسفل المسار السابق.

لوحات عرض خارج الشاشة للمقاطع الصوتية واللقطات المميّزة

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

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

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

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

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

تحليل التتبّع الذي تم اختباره بشكل شامل

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

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

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

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

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

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

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

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

الخاتمة

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

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

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

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

التواصل مع فريق "أدوات مطوّري البرامج في Chrome"

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