การวัดประสิทธิภาพด้วยระยะเวลาของเซิร์ฟเวอร์
เผยแพร่แล้ว: 2022-03-10เมื่อดำเนินการเพิ่มประสิทธิภาพการทำงานใดๆ สิ่งแรกที่เราเรียนรู้ก็คือก่อนที่คุณจะสามารถปรับปรุงประสิทธิภาพได้ คุณต้องวัดผลก่อน หากไม่สามารถวัดความเร็วของบางสิ่งได้ เราไม่สามารถบอกได้ว่าการเปลี่ยนแปลงที่ทำขึ้นนั้นกำลังปรับปรุงประสิทธิภาพ ไม่มีผล หรือแม้แต่ทำให้สิ่งต่างๆ แย่ลงไปอีก
พวกเราหลายคนคงคุ้นเคยกับการทำงานกับปัญหาด้านประสิทธิภาพในระดับหนึ่ง นั่นอาจเป็นเรื่องง่ายๆ เหมือนกับการพยายามค้นหาว่าเหตุใด JavaScript บนหน้าเว็บของคุณจึงไม่ทำงานเร็วพอ หรือเหตุใดรูปภาพจึงใช้เวลานานเกินไปที่จะปรากฏบน wifi ของโรงแรมที่ไม่ดี คำตอบสำหรับคำถามประเภทนี้มักพบในสถานที่ที่คุ้นเคย นั่นคือเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์
ตลอดหลายปีที่ผ่านมา เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ได้รับการปรับปรุงเพื่อช่วยเราแก้ไขปัญหาด้านประสิทธิภาพในส่วนหน้าของแอปพลิเคชันของเรา ขณะนี้เบราว์เซอร์มีการตรวจสอบประสิทธิภาพในตัวด้วย ซึ่งจะช่วยติดตามปัญหาส่วนหน้า แต่การตรวจสอบเหล่านี้สามารถแสดงแหล่งที่มาของความช้าอีกแหล่งที่เราไม่สามารถแก้ไขได้ในเบราว์เซอร์ ปัญหานั้นคือเวลาตอบสนองของเซิร์ฟเวอร์ช้า
“เวลาเป็นไบต์แรก”
มีการเพิ่มประสิทธิภาพเบราว์เซอร์เพียงเล็กน้อยเพื่อปรับปรุงหน้าเว็บที่สร้างบนเซิร์ฟเวอร์ได้ช้า ค่าใช้จ่ายนั้นเกิดขึ้นระหว่างเบราว์เซอร์ที่ส่งคำขอไฟล์และรับการตอบกลับ การศึกษาแผนภูมิเครือข่ายแบบน้ำตกของคุณในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จะแสดงความล่าช้านี้ภายใต้หมวดหมู่ "รอ (TTFB)" นี่คือระยะเวลาที่เบราว์เซอร์รอระหว่างการส่งคำขอและรับการตอบกลับ
ในแง่ประสิทธิภาพการทำงานนี้เรียกว่า Time to First Byte ซึ่งเป็นระยะเวลาที่ใช้ก่อนที่เซิร์ฟเวอร์จะเริ่มส่งข้อมูลบางอย่างที่เบราว์เซอร์สามารถเริ่มทำงานได้ สิ่งที่รวมอยู่ในเวลารอนั้นเป็นทุกสิ่งที่เซิร์ฟเวอร์ต้องทำเพื่อสร้างเพจ สำหรับไซต์ทั่วไป ซึ่งอาจเกี่ยวข้องกับการกำหนดเส้นทางคำขอไปยังส่วนที่ถูกต้องของแอปพลิเคชัน การตรวจสอบคำขอ การเรียกหลายครั้งไปยังระบบแบ็กเอนด์ เช่น ฐานข้อมูล และอื่นๆ อาจเกี่ยวข้องกับการเรียกใช้เนื้อหาผ่านระบบเทมเพลต การเรียก API ไปยังบริการของบุคคลที่สาม และอาจรวมถึงการส่งอีเมลหรือการปรับขนาดรูปภาพ งานใดๆ ที่เซิร์ฟเวอร์ทำเพื่อดำเนินการตามคำขอให้เสร็จสิ้นจะถูกบีบอัดลงใน TTFB นั้นรอให้ผู้ใช้พบในเบราว์เซอร์ของตน
แล้วเราจะลดเวลานั้นและเริ่มส่งเพจให้ผู้ใช้เร็วขึ้นได้อย่างไร? นั่นเป็นคำถามใหญ่ และคำตอบก็ขึ้นอยู่กับการสมัครของคุณ นั่นคืองานของการเพิ่มประสิทธิภาพการทำงานเอง สิ่งที่เราต้องทำก่อนคือ การวัด ประสิทธิภาพเพื่อให้สามารถตัดสินประโยชน์ของการเปลี่ยนแปลงใดๆ ได้
ส่วนหัวกำหนดเวลาของเซิร์ฟเวอร์
งานของ Server Timing ไม่ได้ช่วยให้คุณทำกิจกรรมบนเซิร์ฟเวอร์ของคุณได้จริง คุณจะต้องกำหนดเวลาด้วยตัวเองโดยใช้ชุดเครื่องมือที่แพลตฟอร์มแบ็กเอนด์ของคุณมีให้ วัตถุประสงค์ของเวลาเซิร์ฟเวอร์คือการระบุว่าสามารถสื่อสารการวัดเหล่านั้นไปยังเบราว์เซอร์ได้อย่างไร
วิธีนี้ทำได้ง่ายมาก โปร่งใสต่อผู้ใช้ และมีผลกระทบต่อน้ำหนักหน้าเว็บของคุณน้อยที่สุด ข้อมูลจะถูกส่งเป็นชุดส่วนหัวการตอบสนอง 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”
นี้แล้วจะปรากฏขึ้นพร้อมกับการกำหนดเวลา
สิ่งหนึ่งที่คุณอาจสังเกตเห็นก็คือแถบเวลาไม่แสดงในรูปแบบน้ำตก นี่เป็นเพียงเพราะ Server Timing ไม่ได้พยายามสื่อสาร ลำดับ ของเวลา เพียงแต่ตัววัดดิบเอง
การใช้ระยะเวลาของเซิร์ฟเวอร์
การใช้งานที่แน่นอนภายในแอปพลิเคชันของคุณจะขึ้นอยู่กับสถานการณ์เฉพาะของคุณ แต่หลักการก็เหมือนกัน ขั้นตอนจะเป็นดังนี้:
- เวลาดำเนินการบางอย่าง
- รวบรวมผลการจับเวลา
- ส่งออกส่วนหัว 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"
การดำเนินการที่มีอยู่
เมื่อพิจารณาว่าระยะเวลาของเซิร์ฟเวอร์มีประโยชน์เพียงใด มีการใช้งานค่อนข้างน้อยที่ฉันหาได้ แพ็คเกจ 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