איך למדוד ביצועים של גרפיקה בדפדפן

אילמרי הייקינן

השוואת גרפיקה לדפדפן על קצה המזלג: צייר כמה שיותר, תוך שמירה על קצב פריימים חלק. כשקצב הפריימים ירד, תדעו כמה אפשר למשוך כל פריים. סוף הפוסט. לא, נכון? אוקיי, עכשיו אסביר קצת יותר.

זמן לדוגמה! הנה קטע קוד קטן עם פונקציית 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

אפשר לראות איך נקודת ההשוואה ממשיכה לצבור נתונים עוד ועוד עד שהיא מגיעה לנקודה שבה היא איטית יותר. זוהי דרך פשוטה ונחמדה לגלות כמה תוכלו למשוך בקצב פריימים חלק. תוכל גם להוסיף פונקציית ציור משלך לדוגמה ולערוך השוואה מותאמת אישית, איזה כיף!

אזהרות ומכשולים נפוצים בעת השוואה בין גרפיקה של דפדפן

אז אם הדוגמה שלמעלה היא הדרך הנחמדה לעשות זאת, מהן הדרכים הנחמדות? הדרכים שמובילות לביצוע השוואה של דברים לא קשורים, או הדרכים שבהן אתם מקבלים מדדי ביצועים מוזרים, שנראה שאין להם כל קשר למהירות הפעולה של האפליקציה שלכם. שמחתי ששאלת, הנה שתי השאלות הנפוצות ביותר שראיתי באינטרנט.

מדידה של קצב ה-FPS המקסימלי: מציירים קצת מכל פריים ומודדים את ה-FPS. היא לא פועלת כראוי למדידת ביצועי הגרפיקה ב-Chrome כי הטמעת הגרפיקה הבסיסית מסונכרנת לקצב הרענון של המסך (כך שאתם מקבלים עד 60 עדכונים של המסך בשנייה). מדידת המהירות של שיחת ציור לא תועיל במיוחד, מכיוון שמערכת השרטוט של Chrome מכניסה את פקודות הציור למאגר פקודות שמופעל ברענון המסך הבא.

השימוש ב-setTimeout למדידת ביצועי גרפיקה הוא רעיון גרוע נוסף. מרווח הזמן setTimeout מוגבל ל-4 אלפיות שנייה בדפדפנים, כך שהמקסימום שאפשר לצאת ממנו הוא 250 FPS. בעבר, לדפדפנים היו מרווחי זמן מינימליים שונים, לכן ייתכן שהיה לך נקודת השוואה טריוויאלית מנותקת שהציגה את דפדפן A פועל ב-250 FPS (מרווח של 4 אלפיות שנייה) ואת דפדפן B פועל ב-100 FPS (מרווח של 10 אלפיות שנייה). ברור ש-A הוא מהיר יותר! לא! יכול להיות ש-B ביצעה את קוד השרטוט מהר יותר מ-A. למשל, א' נמשכה 3 אלפיות השנייה ו-B נמשכה אלפיות השנייה. ההגדרה לא משפיעה על ה-FPS, כי זמן השליפה קטן ממרווח הזמן המינימלי setTimeout. ואם הדפדפן מעובד באופן אסינכרוני, כל ההשערות מושבתות. אל תשתמש ב-setTimeout אלא אם אתה יודע מה אתה עושה.

איך עושים את זה?

דרך טובה יותר להשוואה היא להשתמש בעומס ציור מציאותי ולהכפיל אותו עד שקצב הפריימים יתחיל להשתנות. לדוגמה, אם אתם כותבים משחק מלמעלה-למטה עם פני שטח של מפת אריחים, נסו לצייר את מפת האריחים בכל פריים ולראות אם הוא פועל בקצב של 60 FPS. אם כן, מגדילים את העומס (צריך לצייר מפת אריחים פעמיים בכל מסגרת, עם רווח ביניהן). ממשיכים בהגדלה עד שה-FPS יירד לרמה יציבה חדשה. עכשיו אתם יודעים כמה שכבות של מפת משבצות אפשר לשרטט בכל מסגרת.

לאפליקציות גרפיקה שונות יש צרכים שונים, ולכן כדאי להביא זאת בחשבון את נקודות ההשוואה שלכם. מודדים את תכונות הגרפיקה שבהן משתמשים באפליקציה. כשמגלים תרחיש איטי, כדאי לצמצם אותו לקטע הקוד הקטן ביותר שמשחזר אותו (ולהגיש דוח על באג בכתובת new.crbug.com אם התהליך אמור להיות מהיר יותר).

כדי ללמוד כיצד לכתוב קוד גרפי באינטרנט עם ביצועים גבוהים, עיין בהרצאה של Google I/O 2012 מאת Nat Duca וטום וילציוס מצוות Chrome GPU.