เรียนรู้ข้อมูลเบื้องต้นเกี่ยวกับการใช้ API การนำทางและระยะเวลาทรัพยากร เพื่อประเมินประสิทธิภาพการโหลดในฟิลด์
หากเคยใช้การควบคุมการเชื่อมต่อในแผงเครือข่ายในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์ (หรือ Lighthouse ใน Chrome) เพื่อประเมินประสิทธิภาพการโหลด แสดงว่าเครื่องมือเหล่านั้นใช้ได้สะดวกเพียงใดสำหรับการปรับแต่งประสิทธิภาพ คุณสามารถวัดผลของการเพิ่มประสิทธิภาพได้อย่างรวดเร็วด้วยความเร็วในการเชื่อมต่อพื้นฐานที่เสถียรและสม่ำเสมอ ปัญหาเดียวคือการทดสอบสังเคราะห์ ซึ่งจะให้ข้อมูลในห้องปฏิบัติการ ไม่ใช่ข้อมูลภาคสนาม
การทดสอบสังเคราะห์ไม่ได้ที่ไม่ดี แต่ไม่ได้แสดงถึงความเร็วที่เว็บไซต์โหลดสำหรับผู้ใช้จริง ซึ่งต้องใช้ข้อมูลฟิลด์ ซึ่งสามารถรวบรวมได้จาก Navigation Timing และ Resource Timing API
API ที่จะช่วยคุณประเมินประสิทธิภาพการโหลดในภาคสนาม
Navigation Timing และ Resource Timing เป็น API ที่คล้ายกัน 2 รายการและมีการทับซ้อนกันอย่างมากซึ่งวัด 2 สิ่งที่แตกต่างกัน ได้แก่
- เวลาการนำทางจะวัดความเร็วของคำขอสำหรับเอกสาร HTML (นั่นคือคำขอการนำทาง)
- ระยะเวลาของทรัพยากรจะวัดความเร็วของคำขอสำหรับทรัพยากรที่ขึ้นอยู่กับเอกสาร เช่น CSS, JavaScript, รูปภาพ และอื่นๆ
โดย API เหล่านี้จะเปิดเผยข้อมูลในบัฟเฟอร์รายการประสิทธิภาพ ซึ่งเข้าถึงได้ในเบราว์เซอร์ด้วย JavaScript คุณค้นหาบัฟเฟอร์ประสิทธิภาพได้หลายวิธี แต่วิธีที่ใช้กันโดยทั่วไปคือการใช้ performance.getEntriesByType
ดังนี้
// Get Navigation Timing entries:
performance.getEntriesByType('navigation');
// Get Resource Timing entries:
performance.getEntriesByType('resource');
performance.getEntriesByType
ยอมรับสตริงที่อธิบายประเภทของรายการที่คุณต้องการดึงจากบัฟเฟอร์รายการประสิทธิภาพ 'navigation'
และ 'resource'
จะดึงข้อมูลช่วงเวลาสำหรับ Navigation Timing และ Resource Timing API ตามลำดับ
ข้อมูลที่ API เหล่านี้ให้อาจมีมากเกินไป แต่ข้อมูลเหล่านี้คือกุญแจสำคัญในการวัดประสิทธิภาพการโหลดในภาคสนาม เนื่องจากคุณสามารถรวบรวมช่วงเวลาเหล่านี้จากผู้ใช้ขณะที่เข้าชมเว็บไซต์ของคุณ
อายุการใช้งานและระยะเวลาของคำขอเครือข่าย
การรวบรวมและการวิเคราะห์ช่วงเวลาของการนำทางและเวลาที่ทรัพยากรนั้นก็เหมือนกับโบราณคดี นั่นคือการทบทวนอายุการใช้งานของคำขอเครือข่ายที่ปรากฏอยู่ชั่วขณะ บางครั้งก็จะช่วยให้เห็นภาพแนวคิดและส่วนที่มีความกังวลเกี่ยวกับคำขอเครือข่าย เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์ก็ช่วยได้
ระยะเวลาของคำขอเครือข่ายมีช่วงเวลาที่แตกต่างกัน เช่น การค้นหา DNS, การสร้างการเชื่อมต่อ, การเจรจา TLS และอื่นๆ เวลาเหล่านี้จะแสดงเป็น DOMHighResTimestamp
รายละเอียดของการจับเวลาอาจลดลงถึงไมโครวินาทีหรือปัดขึ้นเป็นมิลลิวินาที ทั้งนี้ขึ้นอยู่กับเบราว์เซอร์ของคุณ เรามาดูรายละเอียดของขั้นตอนเหล่านี้กัน และความเกี่ยวข้องกับ Navigation Timing และ Resource Timing
การค้นหา DNS
เมื่อผู้ใช้ไปที่ URL ระบบจะค้นหาระบบชื่อโดเมน (DNS) เพื่อแปลโดเมนเป็นที่อยู่ IP กระบวนการนี้อาจใช้เวลานาน คุณควรวัดในภาคสนามด้วยซ้ำ Navigation Timing และ Resource Timing แสดงการจับเวลาที่เกี่ยวข้องกับ DNS 2 รายการ ได้แก่
domainLookupStart
คือเวลาที่การค้นหา DNS เริ่มต้นdomainLookupEnd
คือเวลาที่การค้นหา DNS สิ้นสุดลง
การคำนวณเวลาในการค้นหา DNS ทั้งหมดคำนวณได้โดยลบเมตริกเริ่มต้นออกจากเมตริกสิ้นสุด ดังนี้
// Measuring DNS lookup time
const [pageNav] = performance.getEntriesByType('navigation');
const totalLookupTime = pageNav.domainLookupEnd - pageNav.domainLookupStart;
การต่อรองการเชื่อมต่อ
อีกปัจจัยหนึ่งที่มีผลต่อประสิทธิภาพการโหลดคือการเจรจาการเชื่อมต่อ ซึ่งเป็นเวลาในการตอบสนองที่เกิดขึ้นเมื่อเชื่อมต่อกับเว็บเซิร์ฟเวอร์ หากมีการใช้ HTTPS กระบวนการนี้จะรวมเวลาในการเจรจา TLS ด้วย ระยะการเชื่อมต่อประกอบด้วย 3 ช่วงเวลา ได้แก่
connectStart
คือเวลาที่เบราว์เซอร์เริ่มเปิดการเชื่อมต่อกับเว็บเซิร์ฟเวอร์secureConnectionStart
จะทำเครื่องหมายเวลาที่ไคลเอ็นต์เริ่มต้นการเจรจา TLSconnectEnd
คือเมื่อสร้างการเชื่อมต่อกับเว็บเซิร์ฟเวอร์
การวัดเวลาในการเชื่อมต่อทั้งหมดคล้ายกับการวัดเวลาในการค้นหา DNS ทั้งหมด โดยหักลบเวลาเริ่มต้นออกจากเวลาสิ้นสุด อย่างไรก็ตาม ยังมีพร็อพเพอร์ตี้ secureConnectionStart
เพิ่มเติมที่อาจมีสถานะเป็น 0
หากไม่ได้ใช้ HTTPS หรือหากการเชื่อมต่อเป็นแบบคงอยู่ หากต้องการวัดเวลาในการเจรจา TLS โปรดคำนึงถึงสิ่งต่อไปนี้
// Quantifying total connection time
const [pageNav] = performance.getEntriesByType('navigation');
const connectionTime = pageNav.connectEnd - pageNav.connectStart;
let tlsTime = 0; // <-- Assume 0 to start with
// Was there TLS negotiation?
if (pageNav.secureConnectionStart > 0) {
// Awesome! Calculate it!
tlsTime = pageNav.connectEnd - pageNav.secureConnectionStart;
}
เมื่อการค้นหา DNS และการเจรจาการเชื่อมต่อสิ้นสุดลง เวลาที่เกี่ยวข้องกับการดึงข้อมูลเอกสารและทรัพยากรที่ต้องอาศัยกันจะมีผล
คำขอและการตอบกลับ
ปัจจัย 2 ประเภทส่งผลต่อประสิทธิภาพในการโหลด ได้แก่
- ปัจจัยภายนอก: ได้แก่ เวลาในการตอบสนองและแบนด์วิดท์ นอกจากการเลือกบริษัทโฮสติ้งและ CDN แล้ว บริษัท (ส่วนใหญ่) ก็ไม่สามารถควบคุมได้ เนื่องจากผู้ใช้สามารถเข้าถึงเว็บได้จากทุกที่
- ปัจจัยภายใน: ได้แก่ สถาปัตยกรรมของเซิร์ฟเวอร์และฝั่งไคลเอ็นต์ ตลอดจนขนาดทรัพยากรและความสามารถในการปรับแต่งเพื่อสิ่งต่างๆ เหล่านี้ ซึ่งอยู่ภายใต้การควบคุมของเรา
ปัจจัยทั้ง 2 ประเภทส่งผลต่อประสิทธิภาพการโหลด การจับเวลาที่เกี่ยวข้องกับปัจจัยเหล่านี้มีความสำคัญอย่างยิ่ง เนื่องจากอธิบายระยะเวลาที่ใช้ในการดาวน์โหลดทรัพยากร ทั้ง Navigation Timing และ Resource Timing จะอธิบายประสิทธิภาพของการโหลดด้วยเมตริกต่อไปนี้
fetchStart
จะทำเครื่องหมายเมื่อเบราว์เซอร์เริ่มดึงข้อมูลทรัพยากร (Resource Timing) หรือเอกสารสำหรับคำขอการนำทาง (Navigation Timing) ข้อมูลนี้จะปรากฏก่อนคำขอจริง และเป็นจุดที่เบราว์เซอร์กำลังตรวจสอบแคช (เช่น HTTP และCache
อินสแตนซ์)workerStart
จะทําเครื่องหมายเมื่อเริ่มจัดการคําขอภายในตัวแฮนเดิลเหตุการณ์fetch
ของ Service Worker การดำเนินการนี้จะเป็น0
เมื่อไม่มี Service Worker กำลังควบคุมหน้าปัจจุบันrequestStart
คือเวลาที่เบราว์เซอร์สร้างคําขอresponseStart
คือเมื่อไบต์แรกของการตอบกลับมาถึงresponseEnd
คือเวลาที่ไบต์สุดท้ายของการตอบกลับมาถึง
การจับเวลาเหล่านี้ช่วยให้คุณวัดประสิทธิภาพการโหลดได้ในหลายๆ ด้าน เช่น การค้นหาแคชภายในโปรแกรมทำงานของบริการและเวลาในการดาวน์โหลด ดังนี้
// Cache seek plus response time of the current document
const [pageNav] = performance.getEntriesByType('navigation');
const fetchTime = pageNav.responseEnd - pageNav.fetchStart;
// Service worker time plus response time
let workerTime = 0;
if (pageNav.workerStart > 0) {
workerTime = pageNav.responseEnd - pageNav.workerStart;
}
นอกจากนี้ คุณยังวัดเวลาในการตอบสนองของคําขอ/การตอบกลับในด้านอื่นๆ ได้ด้วย
const [pageNav] = performance.getEntriesByType('navigation');
// Request time only (excluding redirects, DNS, and connection/TLS time)
const requestTime = pageNav.responseStart - pageNav.requestStart;
// Response time only (download)
const responseTime = pageNav.responseEnd - pageNav.responseStart;
// Request + response time
const requestResponseTime = pageNav.responseEnd - pageNav.requestStart;
การวัดอื่นๆ ที่คุณทำได้
Navigation Timing และ Resource Timing เป็นประโยชน์มากกว่าที่ตัวอย่างด้านบนสรุป สถานการณ์อื่นๆ เกี่ยวกับช่วงเวลาที่เกี่ยวข้องซึ่งคุณควรสำรวจมีดังนี้
- การเปลี่ยนเส้นทางหน้าเว็บ: การเปลี่ยนเส้นทางเป็นแหล่งที่มาของเวลาในการตอบสนองที่เพิ่มเข้ามาซึ่งถูกมองข้ามไป โดยเฉพาะเชนการเปลี่ยนเส้นทาง เวลาในการตอบสนองเพิ่มขึ้นได้หลายวิธี เช่น การเปลี่ยนเส้นทาง HTTP-to-HTTP รวมถึงการเปลี่ยนเส้นทาง 302/uncached 301 การกำหนดเวลา
redirectStart
,redirectEnd
และredirectCount
มีประโยชน์ในการประเมินเวลาในการตอบสนองของการเปลี่ยนเส้นทาง - การยกเลิกการโหลดเอกสาร: ในหน้าที่เรียกใช้โค้ดในตัวแฮนเดิลเหตุการณ์
unload
เบราว์เซอร์ต้องเรียกใช้โค้ดดังกล่าวก่อนจึงจะไปยังหน้าถัดไปได้unloadEventStart
และunloadEventEnd
วัดการยกเลิกการโหลดเอกสาร - การประมวลผลเอกสาร: เวลาประมวลผลเอกสารอาจไม่ส่งผลตามมา เว้นแต่เว็บไซต์ของคุณจะส่งเพย์โหลด HTML ขนาดใหญ่มาก หากตรงกับสถานการณ์ของคุณ ช่วงเวลา
domInteractive
,domContentLoadedEventStart
,domContentLoadedEventEnd
และdomComplete
อาจมีประโยชน์
การรับข้อมูลเวลาในโค้ดของแอปพลิเคชัน
ตัวอย่างทั้งหมดที่แสดงจนถึงตอนนี้จะใช้ performance.getEntriesByType
แต่มีวิธีอื่นๆ ในการค้นหาบัฟเฟอร์รายการประสิทธิภาพ เช่น performance.getEntriesByName
และ performance.getEntries
วิธีการเหล่านี้ใช้งานได้เมื่อต้องใช้การวิเคราะห์แสงเท่านั้น ส่วนในกรณีอื่นๆ อาจมีงานเทรดหลักที่มากเกินไปได้ด้วยการทำซ้ำรายการจำนวนมาก หรือแม้กระทั่งสำรวจบัฟเฟอร์ประสิทธิภาพซ้ำๆ เพื่อหารายการใหม่
วิธีที่แนะนำสำหรับการรวบรวมรายการจากบัฟเฟอร์รายการประสิทธิภาพคือการใช้ PerformanceObserver
PerformanceObserver
จะคอยฟังรายการประสิทธิภาพและระบุเมื่อเพิ่มลงในบัฟเฟอร์
// Create the performance observer:
const perfObserver = new PerformanceObserver((observedEntries) => {
// Get all resource entries collected so far:
const entries = observedEntries.getEntries();
// Iterate over entries:
for (let i = 0; i < entries.length; i++) {
// Do the work!
}
});
// Run the observer for Navigation Timing entries:
perfObserver.observe({
type: 'navigation',
buffered: true
});
// Run the observer for Resource Timing entries:
perfObserver.observe({
type: 'resource',
buffered: true
});
วิธีรวบรวมช่วงเวลานี้อาจดูแปลกประหลาดเมื่อเทียบกับการเข้าถึงบัฟเฟอร์รายการประสิทธิภาพโดยตรง แต่ควรผูกเทรดหลักกับงานที่ไม่มีจุดประสงค์ที่สำคัญต่อผู้ใช้
บ้าน Phoning Home
เมื่อรวบรวมเวลาทั้งหมดที่ต้องการแล้ว คุณสามารถส่งข้อมูลดังกล่าวไปยังปลายทางเพื่อทำการวิเคราะห์เพิ่มเติมได้ โดยใช้ navigator.sendBeacon
หรือ fetch
ที่ตั้งค่าตัวเลือก keepalive
ไว้ 2 วิธี ทั้ง 2 วิธีจะส่งคำขอไปยังปลายทางที่ระบุในแบบที่ไม่บล็อก และคำขอจะอยู่ในคิวในลักษณะที่ทำให้เซสชันหน้าปัจจุบันหมดลงแล้ว หากจำเป็น
// Caution: If you have lots of performance entries, don't
// do this. This is an example for illustrative purposes.
const data = JSON.stringify(performance.getEntries()));
// The endpoint to transmit the encoded data to
const endpoint = '/analytics';
// Check for fetch keepalive support
if ('keepalive' in Request.prototype) {
fetch(endpoint, {
method: 'POST',
body: data,
keepalive: true,
headers: {
'Content-Type': 'application/json'
}
});
} else if ('sendBeacon' in navigator) {
// Use sendBeacon as a fallback
navigator.sendBeacon(endpoint, data);
}
ในตัวอย่างนี้ สตริง JSON จะมาถึงในเพย์โหลด POST
ซึ่งคุณถอดรหัสและประมวลผล/จัดเก็บไว้ในแบ็กเอนด์ของแอปพลิเคชันได้ตามต้องการ
ใกล้จะเสร็จแล้ว
เมื่อคุณรวบรวมเมตริกแล้ว คุณจะต้องหาวิธีวิเคราะห์ข้อมูลภาคสนามนั้น เมื่อวิเคราะห์ข้อมูลภาคสนาม มีกฎทั่วไป 2-3 ข้อที่ต้องปฏิบัติตามเพื่อให้แน่ใจว่าคุณจะได้ข้อสรุปที่มีความหมาย
- หลีกเลี่ยงค่าเฉลี่ย เนื่องจากไม่ได้แสดงถึงประสบการณ์ของผู้ใช้ใดๆ และอาจบิดเบือนโดยค่าผิดปกติ
- พึ่งพาเปอร์เซ็นไทล์ ในชุดข้อมูลของเมตริกประสิทธิภาพที่อิงตามเวลา ยิ่งน้อยยิ่งดี ซึ่งหมายความว่าเมื่อให้ความสำคัญกับเปอร์เซ็นต์ไทล์ที่ต่ำ จะเป็นการให้ความสำคัญกับประสบการณ์ที่เร็วที่สุดเท่านั้น
- จัดลำดับความสำคัญด้านยาวของค่า เมื่อให้ความสำคัญกับประสบการณ์ที่เปอร์เซ็นไทล์ที่ 75 ขึ้นไป เท่ากับว่าคุณให้ความสำคัญกับเรื่องนั้น นั่นคือประสบการณ์ที่ช้าที่สุด
คำแนะนำนี้ไม่ได้เป็นเพียงแหล่งข้อมูลอย่างละเอียดเกี่ยวกับการนำทางหรือระยะเวลาของทรัพยากร แต่เป็นจุดเริ่มต้น แหล่งข้อมูลเพิ่มเติมบางส่วนที่อาจเป็นประโยชน์กับคุณมีดังนี้
- ข้อกำหนดของเวลาการนำทาง
- ข้อกำหนดเฉพาะการจับเวลาของทรัพยากร
- ResourceTiming ในทางปฏิบัติ
- Navigation Timing API (MDN)
- Resource Timing API (MDN)
คุณจะใช้ API เหล่านี้และข้อมูลที่มีให้ได้ดีขึ้นเพื่อทำความเข้าใจประสิทธิภาพการโหลดของผู้ใช้จริงให้ดียิ่งขึ้น ซึ่งจะเพิ่มความมั่นใจในการวินิจฉัยและแก้ไขปัญหาเกี่ยวกับประสิทธิภาพการโหลดในภาคสนามได้มากขึ้น