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

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

ถึงเวลาแสดงตัวอย่างแล้ว ต่อไปนี้คือข้อมูลโค้ดสั้นๆ ที่มีฟังก์ชันการเปรียบเทียบ tick ฟังก์ชัน tick จะเรียกใช้ฟังก์ชัน draw ที่มีภาระการวาดที่เพิ่มขึ้นเรื่อยๆ จนกว่าการวาดจะใช้เวลานานกว่า 33 มิลลิวินาทีอย่างต่อเนื่อง

var t, previousTime;
var drawLoad = 1;
var slowCount = 0;
var maxSlow = 10;
// Note, you might need to polyfill performance.now and requestAnimationFrame
t = previousTime = performance.now();
var tick = function() {
    var maximumFrameTime = 1000/30; // 30 FPS
    t = performance.now();
    var elapsed = t - previousTime;
    previousTime = t;
    if (elapsed < maximumFrameTime || slowCount < maxSlow) {
        if (elapsed < maximumFrameTime) {
            drawLoad+=10;
        } else {
            slowCount++;
        }
        draw(drawLoad);
        requestAnimationFrame(tick);
    } else {
        // found maximum sustainable load at 30 FPS
        document.getElementById('res').innerHTML = ("could draw "+(drawLoad)+" in " +
            maximumFrameTime + " ms");
    }
};
requestAnimationFrame(tick);

​ ดูตัวอย่างการใช้งานจริงที่ jsFiddle

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

ข้อควรระวังและข้อผิดพลาดที่พบบ่อยเมื่อทำการเปรียบเทียบประสิทธิภาพกราฟิกของเบราว์เซอร์

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

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

การใช้ setTimeout เพื่อวัดประสิทธิภาพกราฟิกก็ไม่ใช่ความคิดที่ดีเช่นกัน ช่วงเวลาของ setTimeout จะจำกัดอยู่ที่ 4 มิลลิวินาทีในเบราว์เซอร์ ดังนั้นค่าสูงสุดที่คุณจะได้รับคือ 250 FPS ที่ผ่านมาเบราว์เซอร์มีช่วงเวลาขั้นต่ำแตกต่างกัน คุณจึงอาจได้การทดสอบการวาดภาพที่ไม่สําคัญซึ่งใช้งานไม่ได้เลยซึ่งแสดงว่าเบราว์เซอร์ กําลังทํางานที่ 250 FPS (ช่วงเวลาขั้นต่ำ 4 มิลลิวินาที) และเบราว์เซอร์ ขําลังทํางานที่ 100 FPS (ช่วงเวลาขั้นต่ำ 10 มิลลิวินาที) เห็นได้ชัดว่า A เร็วกว่า ไม่ใช่ อาจเป็นเพราะ B เรียกใช้โค้ดวาดภาพเร็วกว่า A เช่น A ใช้เวลา 3 มิลลิวินาทีและ B ใช้เวลา 1 มิลลิวินาที จะไม่ส่งผลต่อ FPS เนื่องจากเวลาวาดภาพน้อยกว่าช่วงเวลาต่ำสุดของ setTimeout และหากเบราว์เซอร์แสดงผลแบบอะซิงโครนัส ทุกอย่างก็จบลง อย่าใช้ setTimeout เว้นแต่คุณจะรู้สิ่งที่ทําอยู่

วิธีดำเนินการ

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

แอปพลิเคชันกราฟิกแต่ละประเภทมีความต้องการแตกต่างกัน คุณจึงควรเขียนการเปรียบเทียบโดยคำนึงถึงสิ่งเหล่านี้ วัดฟีเจอร์กราฟิกที่คุณใช้ในแอป เมื่อพบสถานการณ์ที่ช้า ให้ลองลดโค้ดให้เหลือเพียงโค้ดส่วนเล็กๆ ที่ทำให้เกิดปัญหา (และรายงานข้อบกพร่องที่ new.crbug.com หากควรที่จะเร็วขึ้น)

หากต้องการดูวิธีเขียนโค้ดกราฟิกเว็บที่มีประสิทธิภาพสูง โปรดดูการบรรยายของ Nat Duca และ Tom Wiltzius จากทีม GPU ของ Chrome ใน Google I/O 2012