قياس الأداء مع توقيت الخادم
نشرت: 2022-03-10عند القيام بأي نوع من أعمال تحسين الأداء ، فإن أول ما نتعلمه هو أنه قبل أن تتمكن من تحسين الأداء ، يجب عليك قياسه أولاً. بدون القدرة على قياس السرعة التي يعمل بها شيء ما ، لا يمكننا معرفة ما إذا كانت التغييرات التي يتم إجراؤها تعمل على تحسين الأداء ، أو عدم وجود تأثير لها ، أو حتى جعل الأمور أسوأ.
سيكون الكثير منا على دراية بالعمل على مشكلة في الأداء على مستوى ما. قد يكون هذا شيئًا بسيطًا مثل محاولة اكتشاف سبب عدم تشغيل JavaScript على صفحتك قريبًا بما فيه الكفاية ، أو سبب استغراق الصور وقتًا طويلاً للظهور على شبكة wifi سيئة للفنادق. غالبًا ما توجد الإجابة على هذه الأنواع من الأسئلة في مكان مألوف جدًا: أدوات مطور متصفحك.
على مر السنين ، تم تحسين أدوات المطورين لمساعدتنا في استكشاف هذه الأنواع من مشكلات الأداء وإصلاحها في الواجهة الأمامية لتطبيقاتنا. تحتوي المتصفحات الآن على عمليات تدقيق للأداء مضمنة فيها. يمكن أن يساعد ذلك في تعقب مشكلات الواجهة الأمامية ، ولكن يمكن أن تظهر عمليات التدقيق هذه مصدرًا آخر للبطء الذي لا يمكننا إصلاحه في المتصفح. هذه المشكلة هي بطء أوقات استجابة الخادم.
"الوقت حتى البايت الأول"
هناك القليل جدًا من التحسينات التي يمكن تحسينها في المتصفح لتحسين الصفحة التي تكون ببساطة بطيئة في البناء على الخادم. يتم تكبد هذه التكلفة بين المتصفح الذي يقدم طلب الملف وتلقي الرد. ستظهر دراسة مخطط الشبكة الانحداري في أدوات المطور هذا التأخير تحت فئة "انتظار (TTFB)". هذه هي المدة التي ينتظرها المتصفح بين تقديم الطلب وتلقي الرد.
من حيث الأداء ، يُعرف هذا باسم Time to First Byte - مقدار الوقت الذي يستغرقه الخادم قبل أن يبدأ في إرسال شيء يمكن أن يبدأ المتصفح في العمل معه. يشتمل وقت الانتظار هذا على كل ما يحتاج الخادم القيام به لبناء الصفحة. بالنسبة إلى موقع نموذجي ، قد يتضمن ذلك توجيه الطلب إلى الجزء الصحيح من التطبيق ، ومصادقة الطلب ، وإجراء مكالمات متعددة لأنظمة الواجهة الخلفية مثل قواعد البيانات وما إلى ذلك. يمكن أن يتضمن تشغيل المحتوى من خلال أنظمة القوالب ، وإجراء مكالمات API إلى خدمات الجهات الخارجية ، وربما حتى أشياء مثل إرسال رسائل البريد الإلكتروني أو تغيير حجم الصور. يتم سحق أي عمل يقوم به الخادم لإكمال طلب في انتظار TTFB الذي يواجهه المستخدم في متصفحه.
إذن كيف يمكننا تقليل هذا الوقت والبدء في توصيل الصفحة بشكل أسرع للمستخدم؟ حسنًا ، هذا سؤال كبير ، والإجابة تعتمد على طلبك. هذا هو عمل تحسين الأداء نفسه. ما يتعين علينا القيام به أولاً هو قياس الأداء حتى يمكن الحكم على فائدة أي تغييرات.
رأس توقيت الخادم
لا تتمثل مهمة توقيت الخادم في مساعدتك في الواقع على نشاط الوقت على الخادم الخاص بك. ستحتاج إلى القيام بالتوقيت بنفسك باستخدام أي مجموعة أدوات تتيحها لك منصة الواجهة الخلفية. بدلاً من ذلك ، الغرض من توقيت الخادم هو تحديد كيفية توصيل هذه القياسات إلى المستعرض.
طريقة القيام بذلك بسيطة للغاية وشفافة للمستخدم ولها تأثير ضئيل على وزن صفحتك. يتم إرسال المعلومات كمجموعة بسيطة من رؤوس استجابة HTTP.
Server-Timing: db;dur=123, tmpl;dur=56
يوضح هذا المثال نقطتي توقيت مختلفتين تسمى db
و tmpl
. هذه ليست جزءًا من المواصفات - هذه أسماء اخترناها ، في هذه الحالة لتمثيل بعض توقيتات قاعدة البيانات والقوالب على التوالي.
تشير الخاصية dur
إلى عدد المللي ثانية التي استغرقتها العملية حتى تكتمل. إذا نظرنا إلى الطلب في قسم الشبكة في أدوات المطور ، يمكننا أن نرى أنه تمت إضافة التوقيتات إلى المخطط.
يمكن أن يأخذ عنوان Server-Timing
مقاييس متعددة مفصولة بفواصل:
Server-Timing: metric, metric, metric
يمكن لكل مقياس تحديد ثلاث خصائص ممكنة
- اسم قصير للمقياس (مثل
db
في مثالنا) - المدة بالمللي ثانية (معبر عنها بـ
dur=123
) - وصف (يتم التعبير عنه في صورة وصف
desc="My Description"
)
يتم فصل كل خاصية بفاصلة منقوطة كمحدد. يمكننا إضافة أوصاف لمثالنا مثل ذلك:
Server-Timing: db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing"
الخاصية الوحيدة المطلوبة هي name
. يعتبر كل من dur
و desc
اختياريًا ، ويمكن استخدامهما بشكل اختياري عند الحاجة. على سبيل المثال ، إذا كنت بحاجة إلى تصحيح مشكلة توقيت كانت تحدث على خادم أو مركز بيانات وليس آخر ، فقد يكون من المفيد إضافة هذه المعلومات إلى الاستجابة بدون توقيت مرتبط.
Server-Timing: datacenter;desc="East coast data center", db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing”
سيظهر هذا بعد ذلك جنبًا إلى جنب مع التوقيت.
شيء واحد قد تلاحظه هو أن أشرطة التوقيت لا تظهر في نمط الشلال. هذا ببساطة لأن توقيت الخادم لا يحاول توصيل تسلسل التوقيتات ، فقط المقاييس الأولية نفسها.
تنفيذ توقيت الخادم
سيعتمد التنفيذ الدقيق داخل التطبيق الخاص بك على ظروفك المحددة ، لكن المبادئ هي نفسها. ستكون الخطوات دائمًا:
- حان وقت بعض العمليات
- اجمع نتائج التوقيت معًا
- إخراج رأس HTTP
في الكود الكاذب ، قد يبدو توليد الاستجابة كما يلي:
startTimer('db') getInfoFromDatabase() stopTimer('db') startTimer('geo') geolocatePostalAddressWithAPI('10 Downing Street, London, UK') endTimer('geo') outputHeader('Server-Timing', getTimerOutput())
يجب أن تكون أساسيات تنفيذ شيء على هذا النحو مباشرة في أي لغة. يمكن أن يستخدم تطبيق PHP البسيط للغاية وظيفة microtime()
لعمليات التوقيت ، وقد يبدو شيئًا على غرار ما يلي.
class Timers { private $timers = []; public function startTimer($name, $description = null) { $this->timers[$name] = [ 'start' => microtime(true), 'desc' => $description, ]; } public function endTimer($name) { $this->timers[$name]['end'] = microtime(true); } public function getTimers() { $metrics = []; if (count($this->timers)) { foreach($this->timers as $name => $timer) { $timeTaken = ($timer['end'] - $timer['start']) * 1000; $output = sprintf('%s;dur=%f', $name, $timeTaken); if ($timer['desc'] != null) { $output .= sprintf(';desc="%s"', addslashes($timer['desc'])); } $metrics[] = $output; } } return implode($metrics, ', '); } }
سيستخدم البرنامج النصي للاختبار على النحو التالي ، هنا باستخدام usleep()
لإنشاء تأخير مصطنع في تشغيل البرنامج النصي لمحاكاة عملية تستغرق وقتًا لإكمالها.
$Timers = new Timers(); $Timers->startTimer('db'); usleep('200000'); $Timers->endTimer('db'); $Timers->startTimer('tpl', 'Templating'); usleep('300000'); $Timers->endTimer('tpl'); $Timers->startTimer('geo', 'Geocoding'); usleep('400000'); $Timers->endTimer('geo'); header('Server-Timing: '.$Timers->getTimers());
أدى تشغيل هذا الرمز إلى إنشاء رأس يشبه هذا:
Server-Timing: db;dur=201.098919, tpl;dur=301.271915;desc="Templating", geo;dur=404.520988;desc="Geocoding"
التطبيقات الحالية
بالنظر إلى مدى سهولة توقيت الخادم ، هناك عدد قليل نسبيًا من عمليات التنفيذ التي يمكنني العثور عليها. توفر حزمة NPM لتوقيت الخادم طريقة ملائمة لاستخدام توقيت الخادم من مشاريع Node.
إذا كنت تستخدم إطار عمل PHP يستند إلى برمجيات وسيطة ، فإن tuupola / server-time-middleware يوفر خيارًا مفيدًا أيضًا. لقد كنت أستخدم ذلك في الإنتاج على Notist لبضعة أشهر ، ودائمًا ما أترك بعض التوقيتات الأساسية ممكّنة إذا كنت ترغب في رؤية مثال في البرية.
بالنسبة إلى دعم المتصفح ، فإن أفضل ما رأيته هو Chrome DevTools ، وهذا ما استخدمته في لقطات الشاشة في هذه المقالة.
الاعتبارات
يضيف توقيت الخادم نفسه حدًا أدنى من الحمل إلى استجابة HTTP المرسلة عبر السلك. العنوان ضئيل للغاية ويمكن إرساله بشكل عام بأمان دون القلق بشأن الاستهداف للمستخدمين الداخليين فقط. ومع ذلك ، يجدر الاحتفاظ بالأسماء والأوصاف قصيرة حتى لا تضيف نفقات إضافية غير ضرورية.
أكثر ما يثير القلق هو العمل الإضافي الذي قد تقوم به على الخادم لتوقيت صفحتك أو تطبيقك. يمكن أن يكون لإضافة المزيد من الوقت والتسجيل تأثيرًا على الأداء ، لذلك يجدر تطبيق طريقة لتشغيل هذا وإيقاف تشغيله عند الحاجة.
يعد استخدام رأس توقيت الخادم طريقة رائعة للتأكد من إمكانية الوصول إلى جميع معلومات التوقيت من كل من الواجهة الأمامية والخلفية للتطبيق الخاص بك في مكان واحد. شريطة ألا يكون تطبيقك معقدًا للغاية ، يمكن أن يكون سهل التنفيذ ويمكنك أن تكون جاهزًا للعمل في غضون فترة زمنية قصيرة جدًا.
إذا كنت ترغب في قراءة المزيد عن توقيت الخادم ، يمكنك تجربة ما يلي:
- مواصفات توقيت خادم W3C
- تحتوي صفحة MDN في Server Timing على أمثلة وتفاصيل محدثة لدعم المستعرض
- مقالة مثيرة للاهتمام من فريق BBC iPlayer حول استخدامهم لتوقيت الخادم.