ผู้สังเกตการณ์ประสิทธิภาพ - การเข้าถึงข้อมูลประสิทธิภาพอย่างมีประสิทธิภาพ

มาร์ก โคเฮน

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

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

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

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

ตั้งแต่ Chrome 52 เป็นต้นไป อินเทอร์เฟซผู้สังเกตการณ์ประสิทธิภาพจะเปิดใช้โดยค่าเริ่มต้น มาดูวิธีใช้งานกันเลย

<html>
<head>
    <script>
    var observer = new PerformanceObserver(list => {
        list.getEntries().forEach(entry => {
        // Display each reported measurement on console
        if (console) {
            console.log("Name: "       + entry.name      +
                        ", Type: "     + entry.entryType +
                        ", Start: "    + entry.startTime +
                        ", Duration: " + entry.duration  + "\n");
        }
        })
    });
    observer.observe({entryTypes: ['resource', 'mark', 'measure']});
    performance.mark('registered-observer');

    function clicked(elem) {
        performance.measure('button clicked');
    }
    </script>
</head>
<body>
    <button onclick="clicked(this)">Measure</button>
</body>
</html>

หน้าแบบง่ายนี้เริ่มต้นด้วยแท็กสคริปต์ที่กำหนดโค้ด JavaScript บางส่วน:

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

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

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

ผู้สังเกตการณ์ประสิทธิภาพ

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

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