API ระยะเวลาของผู้ใช้

ทำความเข้าใจเว็บแอป

Alex Danilo

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

คุณเพิ่มประสิทธิภาพในสิ่งที่วัดไม่ได้

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

เวลาความละเอียดสูงและ now()

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

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

var myTime = window.performance.now();

มีอินเทอร์เฟซอีกอันหนึ่งที่ชื่อ PerformanceTiming ซึ่งแสดงจำนวนครั้งที่เกี่ยวข้องกับวิธีโหลดเว็บแอปพลิเคชันของคุณ เมธอด now() จะแสดงผลเวลาที่ผ่านไปจากที่เวลา navigationStart ใน PerformanceTiming เกิดขึ้น

ประเภท DOMHighResTimeStamp

เมื่อต้องการจับเวลาเว็บแอปพลิเคชันในอดีต ให้ใช้ Date.now() ซึ่งแสดงผล DOMTimeStamp DOMTimeStamp จะแสดงผลตัวเลขจำนวนเต็มของมิลลิวินาทีเป็นค่า เราได้มีการเปิดตัวประเภทใหม่ที่เรียกว่า DOMHighResTimeStamp เพื่อให้เวลาที่มีความละเอียดสูงซึ่งมีความแม่นยำที่สูงขึ้น ประเภทนี้คือค่าทศนิยมที่แสดงเวลาเป็นมิลลิวินาที แต่เนื่องจากเป็นค่าทศนิยม ค่าจึงอาจเป็นเศษส่วนมิลลิวินาที จึงให้ค่าความแม่นยำเป็นพันวินาที

อินเทอร์เฟซระยะเวลาของผู้ใช้

เมื่อเราได้การประทับเวลาความละเอียดสูงแล้ว ให้ใช้อินเทอร์เฟซระยะเวลาของผู้ใช้เพื่อดึงข้อมูลเวลา

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

ใช้ไป mark()

เมธอดของ mark() เป็นเครื่องมือหลักในชุดเครื่องมือการวิเคราะห์การจับเวลา mark() จัดเก็บการประทับเวลาไว้ให้เรา สิ่งที่เป็นประโยชน์อย่างยิ่งเกี่ยวกับ mark() คือเราสามารถตั้งชื่อการประทับเวลา แล้ว API จะจดจำชื่อและการประทับเวลาเป็นหน่วยเดียว

การโทรไปยัง mark() ณ ที่ต่างๆ ในแอปพลิเคชันของคุณจะช่วยให้คุณทราบว่าต้องใช้เวลานานเท่าใดในการคลิก "ทำเครื่องหมาย" ในเว็บแอปพลิเคชัน

ข้อกำหนดจะระบุชื่อที่แนะนำจำนวนหนึ่งสำหรับเครื่องหมายต่างๆ ที่อาจน่าสนใจและมีความหมายในตัวเองอยู่แล้ว เช่น mark_fully_loaded, mark_fully_visible,mark_above_the_fold เป็นต้น

ตัวอย่างเช่น เราอาจทำเครื่องหมายเมื่อแอปพลิเคชันโหลดเสร็จสมบูรณ์โดยใช้โค้ดต่อไปนี้

window.performance.mark('mark_fully_loaded');

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

กำลังคำนวณค่าที่วัดได้ด้วยmeasure()

เมื่อคุณกำหนดเครื่องหมายการกำกับเวลาแล้ว คุณจะต้องดูเวลาที่ผ่านไประหว่างนั้น คุณใช้เมธอด measure() เพื่อดำเนินการดังกล่าว

เมธอด measure() จะคำนวณเวลาที่ผ่านไประหว่างเครื่องหมายต่างๆ และจะวัดเวลาระหว่างเครื่องหมายของคุณและชื่อเหตุการณ์ที่รู้จักกันดีในอินเทอร์เฟซ PerformanceTiming ได้ด้วย

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

window.performance.measure('measure_load_from_dom', 'domComplete', 'mark_fully_loaded');

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

กำลังทิ้งเครื่องหมายที่มี clearMarks()

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

คุณสามารถกำจัดเครื่องหมายที่ตั้งค่าไว้แล้วได้ง่ายๆ ด้วยการเรียกใช้ clearMarks()

ดังนั้น โค้ดตัวอย่างด้านล่างจะทำลายเครื่องหมายที่มีอยู่ทั้งหมดเพื่อให้คุณตั้งค่าการเรียกใช้เวลาอีกครั้งได้ หากต้องการ

window.performance.clearMarks();

แน่นอนว่าอาจมีบางสถานการณ์ที่คุณอาจจะไม่ต้องการล้างเครื่องหมายทั้งหมดออก ดังนั้นหากต้องการลบเครื่องหมายบางรายการออก คุณก็แค่บอกชื่อเครื่องหมายที่ต้องการลบได้ ตัวอย่างเช่น โค้ดด้านล่างนี้

window.peformance.clearMarks('mark_fully_loaded');

จะกำจัดเครื่องหมายที่เราตั้งค่าในตัวอย่างแรกแต่คงเครื่องหมายอื่นๆ ที่เราตั้งค่าไว้ไว้ตามเดิม

คุณอาจไม่จำเป็นต้องลบมาตรการใดๆ ที่คุณได้ทำไว้ได้เช่นกัน ซึ่งมีวิธีการที่สอดคล้องกับการดำเนินการดังกล่าวที่เรียกว่า clearMeasures() วิธีการทำงานจะเหมือนกับ clearMarks() ทุกประการ แต่จะทํางานกับการวัดที่คุณทําไว้แทน ตัวอย่างเช่น โค้ด:

window.performance.clearMeasures('measure_load_from_dom');

จะนำมาตรวัดที่เราทำในตัวอย่าง measure() ด้านบนออก หากต้องการนำการวัดผลทั้งหมดออก จะมีการทำงานเหมือนกับ clearMarks() กล่าวคือ คุณเรียกใช้ clearMeasures() โดยไม่มีอาร์กิวเมนต์

กำลังดึงข้อมูลเวลาออก

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

ตัวอย่างเช่น เมธอด getEntriesByType() ช่วยให้เราได้เวลาทำเครื่องหมายทั้งหมด หรือเวลาการวัดทั้งหมดของเราหมดเวลาเป็นรายการ เพื่อที่จะได้ทำซ้ำและสรุปข้อมูล ข้อดีก็คือระบบจะส่งคืนรายการตามลําดับเวลา ดังนั้นคุณจะเห็นเครื่องหมายต่างๆ ที่เรียงตามลำดับในเว็บแอปพลิเคชันของคุณ

โค้ดด้านล่างนี้

var items = window.performance.getEntriesByType('mark');

ส่งกลับรายการเครื่องหมายการค้าทั้งหมดที่ถูกตีในเว็บแอปพลิเคชันของเรา พร้อมกับโค้ด:

var items = window.performance.getEntriesByType('measure');

ส่งกลับรายการมาตรการทั้งหมดที่เราทำ

นอกจากนี้ คุณยังกลับไปยังรายการได้โดยใช้ชื่อเฉพาะที่ได้ระบุไว้ ตัวอย่างเช่น โค้ด:

var items = window.performance.getEntriesByName('mark_fully_loaded');

จะแสดงลิสต์ที่มี 1 รายการพร้อมการประทับเวลา "mark_full_loaded" ในพร็อพเพอร์ตี้ startTime ให้เรา

การกำหนดเวลาคำขอ XHR (ตัวอย่าง)

ตอนนี้เราได้เห็นภาพที่ชัดเจนของ User Timing API แล้ว เราสามารถใช้ API นี้เพื่อวิเคราะห์ระยะเวลาที่ XMLHttpRequests ของเราใช้ในเว็บแอปพลิเคชันของเรา

ก่อนอื่น เราจะแก้ไขคำขอ send() ทั้งหมดเพื่อสร้างการเรียกฟังก์ชันที่สร้างเครื่องหมาย และขณะเดียวกันก็เปลี่ยนการเรียกกลับที่สำเร็จด้วยการเรียกใช้ฟังก์ชันที่กำหนดเครื่องหมายอื่น จากนั้นจะสร้างการวัดระยะเวลาที่คำขอใช้

ดังนั้น โดยปกติแล้ว XMLHttpRequest ของเราจะมีลักษณะดังนี้

var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
  do_something(e.responseText);
}
myReq.send();

สำหรับตัวอย่างของเรา เราจะเพิ่มตัวนับส่วนกลางเพื่อติดตามจำนวนคำขอและยังใช้สำหรับจัดเก็บมาตรวัดของแต่ละคำขอที่ส่งเข้ามาด้วย โค้ดซึ่งมีลักษณะดังนี้

var reqCnt = 0;

var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
  window.performance.mark('mark_end_xhr');
  reqCnt++;
  window.performance.measure('measure_xhr_' + reqCnt, 'mark_start_xhr', 'mark_end_xhr');
  do_something(e.responseText);
}
window.performance.mark('mark_start_xhr');
myReq.send();

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

เมื่อเว็บแอปพลิเคชันได้ส่งคำขอจำนวนมากแล้ว เราสามารถส่งข้อมูลทั้งหมดไปยังคอนโซลได้โดยใช้โค้ดด้านล่างนี้:

var items = window.performance.getEntriesByType('measure');
for (var i = 0; i < items.length; ++i) {
  var req = items[i];
  console.log('XHR ' + req.name + ' took ' + req.duration + 'ms');
}

บทสรุป

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