การวัดประสิทธิภาพด้วยระยะเวลาของเซิร์ฟเวอร์

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ ส่วนหัวของเวลาเซิร์ฟเวอร์ให้วิธีการที่ไม่ต่อเนื่องและสะดวกในการสื่อสารกำหนดเวลาประสิทธิภาพของเซิร์ฟเวอร์ส่วนหลังไปยังเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ในเบราว์เซอร์ การเพิ่มข้อมูลเวลาในแอปพลิเคชันของคุณทำให้คุณสามารถตรวจสอบประสิทธิภาพแบ็คเอนด์และฟรอนต์เอนด์ได้ในที่เดียว

เมื่อดำเนินการเพิ่มประสิทธิภาพการทำงานใดๆ สิ่งแรกที่เราเรียนรู้ก็คือก่อนที่คุณจะสามารถปรับปรุงประสิทธิภาพได้ คุณต้องวัดผลก่อน หากไม่สามารถวัดความเร็วของบางสิ่งได้ เราไม่สามารถบอกได้ว่าการเปลี่ยนแปลงที่ทำขึ้นนั้นกำลังปรับปรุงประสิทธิภาพ ไม่มีผล หรือแม้แต่ทำให้สิ่งต่างๆ แย่ลงไปอีก

พวกเราหลายคนคงคุ้นเคยกับการทำงานกับปัญหาด้านประสิทธิภาพในระดับหนึ่ง นั่นอาจเป็นเรื่องง่ายๆ เหมือนกับการพยายามค้นหาว่าเหตุใด JavaScript บนหน้าเว็บของคุณจึงไม่ทำงานเร็วพอ หรือเหตุใดรูปภาพจึงใช้เวลานานเกินไปที่จะปรากฏบน wifi ของโรงแรมที่ไม่ดี คำตอบสำหรับคำถามประเภทนี้มักพบในสถานที่ที่คุ้นเคย นั่นคือเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์

ตลอดหลายปีที่ผ่านมา เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ได้รับการปรับปรุงเพื่อช่วยเราแก้ไขปัญหาด้านประสิทธิภาพในส่วนหน้าของแอปพลิเคชันของเรา ขณะนี้เบราว์เซอร์มีการตรวจสอบประสิทธิภาพในตัวด้วย ซึ่งจะช่วยติดตามปัญหาส่วนหน้า แต่การตรวจสอบเหล่านี้สามารถแสดงแหล่งที่มาของความช้าอีกแหล่งที่เราไม่สามารถแก้ไขได้ในเบราว์เซอร์ ปัญหานั้นคือเวลาตอบสนองของเซิร์ฟเวอร์ช้า

“เวลาเป็นไบต์แรก”

มีการเพิ่มประสิทธิภาพเบราว์เซอร์เพียงเล็กน้อยเพื่อปรับปรุงหน้าเว็บที่สร้างบนเซิร์ฟเวอร์ได้ช้า ค่าใช้จ่ายนั้นเกิดขึ้นระหว่างเบราว์เซอร์ที่ส่งคำขอไฟล์และรับการตอบกลับ การศึกษาแผนภูมิเครือข่ายแบบน้ำตกของคุณในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จะแสดงความล่าช้านี้ภายใต้หมวดหมู่ "รอ (TTFB)" นี่คือระยะเวลาที่เบราว์เซอร์รอระหว่างการส่งคำขอและรับการตอบกลับ

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

ในแง่ประสิทธิภาพการทำงานนี้เรียกว่า Time to First Byte ซึ่งเป็นระยะเวลาที่ใช้ก่อนที่เซิร์ฟเวอร์จะเริ่มส่งข้อมูลบางอย่างที่เบราว์เซอร์สามารถเริ่มทำงานได้ สิ่งที่รวมอยู่ในเวลารอนั้นเป็นทุกสิ่งที่เซิร์ฟเวอร์ต้องทำเพื่อสร้างเพจ สำหรับไซต์ทั่วไป ซึ่งอาจเกี่ยวข้องกับการกำหนดเส้นทางคำขอไปยังส่วนที่ถูกต้องของแอปพลิเคชัน การตรวจสอบคำขอ การเรียกหลายครั้งไปยังระบบแบ็กเอนด์ เช่น ฐานข้อมูล และอื่นๆ อาจเกี่ยวข้องกับการเรียกใช้เนื้อหาผ่านระบบเทมเพลต การเรียก API ไปยังบริการของบุคคลที่สาม และอาจรวมถึงการส่งอีเมลหรือการปรับขนาดรูปภาพ งานใดๆ ที่เซิร์ฟเวอร์ทำเพื่อดำเนินการตามคำขอให้เสร็จสิ้นจะถูกบีบอัดลงใน TTFB นั้นรอให้ผู้ใช้พบในเบราว์เซอร์ของตน

แผงเครือข่ายใน Chrome DevTools แสดงการตรวจสอบคำขอหน้าเดียว
การตรวจสอบคำขอเอกสารจะแสดงเวลาที่เบราว์เซอร์ใช้ในการรอการตอบกลับจากเซิร์ฟเวอร์

แล้วเราจะลดเวลานั้นและเริ่มส่งเพจให้ผู้ใช้เร็วขึ้นได้อย่างไร? นั่นเป็นคำถามใหญ่ และคำตอบก็ขึ้นอยู่กับการสมัครของคุณ นั่นคืองานของการเพิ่มประสิทธิภาพการทำงานเอง สิ่งที่เราต้องทำก่อนคือ การวัด ประสิทธิภาพเพื่อให้สามารถตัดสินประโยชน์ของการเปลี่ยนแปลงใดๆ ได้

ส่วนหัวกำหนดเวลาของเซิร์ฟเวอร์

งานของ Server Timing ไม่ได้ช่วยให้คุณทำกิจกรรมบนเซิร์ฟเวอร์ของคุณได้จริง คุณจะต้องกำหนดเวลาด้วยตัวเองโดยใช้ชุดเครื่องมือที่แพลตฟอร์มแบ็กเอนด์ของคุณมีให้ วัตถุประสงค์ของเวลาเซิร์ฟเวอร์คือการระบุว่าสามารถสื่อสารการวัดเหล่านั้นไปยังเบราว์เซอร์ได้อย่างไร

วิธีนี้ทำได้ง่ายมาก โปร่งใสต่อผู้ใช้ และมีผลกระทบต่อน้ำหนักหน้าเว็บของคุณน้อยที่สุด ข้อมูลจะถูกส่งเป็นชุดส่วนหัวการตอบสนอง HTTP อย่างง่าย

 Server-Timing: db;dur=123, tmpl;dur=56

ตัวอย่างนี้สื่อสารจุดเวลาสองจุดที่แตกต่างกันชื่อ db และ tmpl สิ่งเหล่านี้ไม่ได้เป็นส่วนหนึ่งของข้อกำหนด - นี่คือชื่อที่เราได้เลือกไว้ ในกรณีนี้เพื่อแสดงเวลาของฐานข้อมูลและเทมเพลตตามลำดับ

คุณสมบัติ dur ระบุจำนวนมิลลิวินาทีที่การดำเนินการทำให้เสร็จสมบูรณ์ หากเราดูคำขอในส่วนเครือข่ายของเครื่องมือสำหรับนักพัฒนา เราจะเห็นว่ามีการกำหนดเวลาเพิ่มลงในแผนภูมิแล้ว

แผง Timings ของคำขอหน้าใน Chrome DevTools ที่แสดงส่วน Server Timing ใหม่
ส่วน Server Timing ใหม่จะปรากฏขึ้น โดยแสดงการกำหนดเวลาที่กำหนดด้วยส่วนหัว Server-Timing HTTP

ส่วนหัว Server-Timing สามารถแยกเมตริกหลายตัวคั่นด้วยเครื่องหมายจุลภาค:

 Server-Timing: metric, metric, metric

แต่ละตัวชี้วัดสามารถระบุคุณสมบัติที่เป็นไปได้สามประการ

  1. ชื่อย่อ สำหรับเมตริก (เช่น db ในตัวอย่างของเรา)
  2. ระยะเวลา เป็นมิลลิวินาที (แสดงเป็น dur=123 )
  3. คำอธิบาย (แสดงเป็น desc="My Description" )

แต่ละพร็อพเพอร์ตี้คั่นด้วยเครื่องหมายอัฒภาคเป็นตัวคั่น เราสามารถเพิ่มคำอธิบายในตัวอย่างของเราได้ดังนี้:

 Server-Timing: db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing"
แผง Timings ของคำขอหน้าใน Chrome DevTools ที่แสดงคำอธิบายที่ใช้สำหรับเมตริก Server Timing
ชื่อจะถูกแทนที่ด้วยคำอธิบายเมื่อมีให้

คุณสมบัติเดียวที่จำเป็นคือ name ทั้ง dur และ desc เป็นทางเลือก และสามารถใช้เป็นทางเลือกเมื่อจำเป็น ตัวอย่างเช่น หากคุณต้องการดีบักปัญหาเรื่องเวลาที่เกิดขึ้นบนเซิร์ฟเวอร์หนึ่งหรือศูนย์ข้อมูล ไม่ใช่อีกเซิร์ฟเวอร์หนึ่ง การเพิ่มข้อมูลนั้นในการตอบกลับโดยไม่ระบุเวลาอาจเป็นประโยชน์

 Server-Timing: datacenter;desc="East coast data center", db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing”

นี้แล้วจะปรากฏขึ้นพร้อมกับการกำหนดเวลา

แผง Timings ของคำขอหน้าใน Chrome DevTools แสดงการจับเวลาเซิร์ฟเวอร์โดยไม่ได้ตั้งเวลา
ค่า "ศูนย์ข้อมูลชายฝั่งตะวันออก" จะแสดงขึ้น แม้ว่าจะไม่มีการกำหนดเวลาก็ตาม

สิ่งหนึ่งที่คุณอาจสังเกตเห็นก็คือแถบเวลาไม่แสดงในรูปแบบน้ำตก นี่เป็นเพียงเพราะ Server Timing ไม่ได้พยายามสื่อสาร ลำดับ ของเวลา เพียงแต่ตัววัดดิบเอง

การใช้ระยะเวลาของเซิร์ฟเวอร์

การใช้งานที่แน่นอนภายในแอปพลิเคชันของคุณจะขึ้นอยู่กับสถานการณ์เฉพาะของคุณ แต่หลักการก็เหมือนกัน ขั้นตอนจะเป็นดังนี้:

  1. เวลาดำเนินการบางอย่าง
  2. รวบรวมผลการจับเวลา
  3. ส่งออกส่วนหัว HTTP

ใน pseudocode การสร้างการตอบสนองอาจมีลักษณะดังนี้:

 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"
แผงเวลาของคำขอหน้าใน Chrome DevTools แสดงค่าทดสอบที่แสดงอย่างถูกต้อง
การกำหนดเวลาเซิร์ฟเวอร์ที่กำหนดไว้ในตัวอย่างจะแสดงขึ้นในแผงการกำหนดเวลาโดยมีการกำหนดค่าความล่าช้าในสคริปต์ทดสอบของเรา

การดำเนินการที่มีอยู่

เมื่อพิจารณาว่าระยะเวลาของเซิร์ฟเวอร์มีประโยชน์เพียงใด มีการใช้งานค่อนข้างน้อยที่ฉันหาได้ แพ็คเกจ NPM ของเวลาเซิร์ฟเวอร์เสนอวิธีที่สะดวกในการใช้ Server Timing จากโปรเจ็กต์ Node

หากคุณใช้เฟรมเวิร์ก PHP ที่ใช้มิดเดิลแวร์ tuupola/server-timing-middleware ก็มีตัวเลือกที่สะดวกเช่นกัน ฉันใช้สิ่งนี้ในการผลิตบน Notist มาสองสามเดือนแล้ว และฉันจะเปิดการกำหนดเวลาพื้นฐานไว้สองสามตัวเสมอ หากคุณต้องการดูตัวอย่างแบบคร่าวๆ

สำหรับการสนับสนุนเบราว์เซอร์ สิ่งที่ดีที่สุดที่ฉันเคยเห็นคือใน Chrome DevTools และนั่นคือสิ่งที่ฉันได้ใช้สำหรับภาพหน้าจอในบทความนี้

ข้อควรพิจารณา

Server Timing เองเพิ่มโอเวอร์เฮดที่น้อยมากให้กับการตอบสนอง HTTP ที่ส่งกลับมาทางสาย ส่วนหัวมีน้อยมากและโดยทั่วไปแล้วปลอดภัยที่จะส่งโดยไม่ต้องกังวลเกี่ยวกับการกำหนดเป้าหมายไปยังผู้ใช้ภายในเท่านั้น ถึงกระนั้น การรักษาชื่อและคำอธิบายให้สั้นก็คุ้มค่า เพื่อที่คุณจะได้ไม่ต้องเพิ่มค่าใช้จ่ายที่ไม่จำเป็น

สิ่งที่น่ากังวลมากกว่าคืองานพิเศษที่คุณอาจทำบนเซิร์ฟเวอร์เพื่อจับเวลาเพจหรือแอปพลิเคชันของคุณ การเพิ่มเวลาและการบันทึกเพิ่มเติมอาจส่งผลต่อประสิทธิภาพการทำงาน ดังนั้นควรใช้วิธีการเปิดและปิดเมื่อจำเป็น

การใช้ส่วนหัวของเวลาเซิร์ฟเวอร์เป็นวิธีที่ยอดเยี่ยมในการตรวจสอบให้แน่ใจว่าข้อมูลเวลาทั้งหมดจากทั้งส่วนหน้าและส่วนหลังของแอปพลิเคชันของคุณสามารถเข้าถึงได้จากที่เดียว หากแอปพลิเคชันของคุณไม่ซับซ้อนเกินไป สามารถนำไปใช้ได้ง่าย และคุณสามารถพร้อมใช้งานได้ภายในระยะเวลาอันสั้น

หากคุณต้องการอ่านเพิ่มเติมเกี่ยวกับ Server Timing คุณอาจลองทำสิ่งต่อไปนี้:

  • ข้อกำหนดเกี่ยวกับเวลาของเซิร์ฟเวอร์ W3C
  • หน้า MDN บน Server Timing มีตัวอย่างและรายละเอียดล่าสุดของการสนับสนุนเบราว์เซอร์
  • บทความที่น่าสนใจจากทีม BBC iPlayer เกี่ยวกับการใช้ Server Timing