يعمل أمر Yandex speed على تحسين نتائج البحث يدويًا. القيام بذلك بشكل أعمى أمر صعب وغالبًا ما يكون عديم الفائدة. لذلك ، بنت الشركة بنية تحتية لجمع المقاييس ، واختبار السرعة وتحليل البيانات.
يعرف مطور واجهات Yandex
Andrei Prokopyuk (
Andre_487 ) حول المقاييس التي يجب استخدامها وكيفية تحسين كل شيء.

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

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

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

لم نبدأ في طرح الميزة باستخدام الخطوط. بعد كل شيء ، تبدو هذه الأرقام صغيرة حتى تتذكر حجم الخدمة. في الواقع ، واحد ونصف بالمائة - مئات الآلاف من الناس.
بالإضافة إلى ذلك ، السرعة لها تأثير تراكمي. للحصول على تحديث واحد مع حصة لم تتم المطالبة بها - سيتبع 0.4٪ المزيد والمزيد. في Yandex ، يتم طرح هذه الميزات بالعشرات يوميًا ، وإذا لم تقاتل مقابل كل حصة ، فلن تدوم طويلاً وتصل إلى 10٪.
LS Caching History
ترتبط هذه القصة بحقيقة أننا نضمن الكثير من المحتوى الثابت في الصفحة.

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

ارتفع متوسط وقت تسليم HTML (المقياس الرئيسي في وقت تطوير التحسين) بنسبة 12٪ ، وهو عدد كبير. ولكن في الوقت نفسه ، الوقت حتى تم رسم الرأس ، قبل بدء تحليل المحتوى ، وقبل تهيئة JavaScript. كما قلل الوقت إلى النقرة الأولى. النسبة المئوية صغيرة - 0.6 ، ولكن إذا كنت تتذكر المقياس ...

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

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

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

مع هذه المكالمة ، نحصل على مجموعة من أحداث التقديم. حتى الآن ، يتم دعم نوعين من الأحداث: الطلاء الأول - أي عرض وطلاء أول محتوى بالكامل - أي عرض لمحتوى بخلاف الخلفية البيضاء لعلامة التبويب الفارغة ومحتوى الخلفية للصفحة.
لذا نحصل على مجموعة من الأحداث ، ونقوم بتصفية الطلاء الأول للمحتوى وإرساله بمعرف معين.
حان الوقت لأول طلاء ذي معنى
لا يوجد أي حدث في واجهة برمجة تطبيقات Paint Timing يشير إلى أنه تم عرض محتوى هام على الصفحة. هذا يرجع إلى حقيقة أن هذا المحتوى على كل صفحة مختلف. إذا كنا نتحدث عن خدمة الفيديو ، فإن الشيء الرئيسي هو المشغل ، في نتائج البحث - أول نتيجة غير إعلانية. هناك الكثير من الخدمات ، ولم يتم تطوير API عالمي حتى الآن. ولكن هنا تلعب العكازات الجيدة والمثبتة.
هناك مدرستان للعكازات في Yandex لقياس هذا المقياس: استخدام RequestAnimationFrame والقياس باستخدام InterceptionObserver.
في RequestAnimationFrame ، يتم قياس التقديم باستخدام فاصل زمني.

افترض أن هناك بعض المحتوى المهم. هنا div مع المحتوى الرئيسي للفئة. يتم وضع برنامج نصي أمامه ، حيث يتم استدعاء RequestAnimationFrame مرتين.
في رد الاتصال للمكالمة الأولى ، اكتب الحد السفلي للفاصل الزمني. في رد اتصال الثانية - الأعلى. ويرجع ذلك إلى بنية الإطار التي يعرضها المتصفح.

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

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

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

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

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

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

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

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

نقوم بنقل بيانات مقياس معين إلى قلم خاص على الواجهة الخلفية وجمعها في المستودع.

هنا ، يتم تعيين تجميع البيانات بشكل تقليدي كاستعلام SQL. فيما يلي التجميعات الرئيسية التي نأخذها في الاعتبار عادةً بواسطة مقاييس السرعة: المتوسط الحسابي والمجموعة المئوية (50 ، 75 ، 95 ، 99).

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

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

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

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

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

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

تشكل المؤشرات الحمراء والخضراء ممرًا آمنًا. في حين أن المتوسط المتري والمتحرك يتقلب بينهما - كل شيء طبيعي ، فهذه تقلبات عادية. ولكن إذا غادروا المنطقة الآمنة ، يتم تشغيل المراقبة.

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

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

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

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

كيف تفعل ذلك بنفسك؟
يمكنك تنفيذ قياسات السرعة بطريقتين. الأول هو أن تفعل كل شيء بنفسك.

مقبض لتلقي البيانات من العملاء ، وواجهة خلفية ، تضع كل هذا في قاعدة بيانات ، MongoDB ، PostgreSQL ، MySQL ، وأي DBMS (لديهم تجميعات خارج الصندوق) ، بالإضافة إلى واحد من العديد من الحلول مفتوحة المصدر - من أجل رسم الرسوم البيانية وترتيب المراقبة.
الحل الثاني هو استخدام أنظمة التحليلات Yandex Metric أو Google Analytics. على مثال Yandex Metrics ، يبدو هذا.

فيما يلي المقاييس التي يوفرها المقياس للمستخدم خارج الصندوق. بالطبع ، هذا ليس كل ما سبق ، ولكنه شيء بالفعل. يمكن إضافة الباقي يدويًا من خلال إعدادات المستخدم. كما يتوفر اختبار ومراقبة A / B.
الخلاصة
يُعرف مفهوم قياس السرعة عبر الإنترنت الذي تحدثنا عنه باسم RUM - Real User Monitoring. نحن نحبها كثيرًا لدرجة أننا رسمنا شعارًا بصخرة رائعة.

هذا النهج جيد لأنه مبني على أرقام من العالم الحقيقي ، تلك المؤشرات التي لدى جمهور خدمتك. باستخدام المقاييس ، يبدو أنك تحصل على تعليقات من كل مستخدم. لذا ابدأ في التحسين ولا تتوقف.
الإعلان في النهاية. إذا كنت تحب هذا الحديث مع HolyJS 2018 Piter ، فمن المحتمل أن تكون مهتمًا بـ HolyJS 2018 Moscow القادم ، والذي سيعقد في 24-25 نوفمبر . هناك لا يمكنك رؤية العديد من تقارير JS-فحسب ، بل اسأل أيضًا أي متحدث في منطقة المناقشة بعد التقرير. وغدًا ، اعتبارًا من 1 نوفمبر ، سترتفع أسعار التذاكر إلى المباراة النهائية ، لذلك اليوم هي الفرصة الأخيرة لشرائها بخصم!