מדידת נתיב העיבוד הקריטי

Ilya Grigorik
Ilya Grigorik

תאריך פרסום: 31 במרץ 2014

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

  • הגישה של Lighthouse מפעילה סדרה של בדיקות אוטומטיות בדף, ואז יוצרת דוח על ביצועי ה-CRP של הדף. הגישה הזו מספקת סקירה כללית מהירה ובסיסית ברמה גבוהה של ביצועי CRP בדף מסוים שנטען בדפדפן, ומאפשרת לבדוק במהירות את הביצועים, לבצע שינויים ולשפר אותם.
  • הגישה של Navigation Timing API מתעדת מדדים של מעקב אחר משתמשים אמיתיים (RUM). כפי שרואים מהשם, המדדים האלה מתועדים מאינטראקציות של משתמשים אמיתיים עם האתר שלכם, ומספקים תמונה מדויקת של ביצועי CRP בעולם האמיתי, כפי שהמשתמשים חווים אותם במגוון מכשירים ותנאי רשת.

באופן כללי, מומלץ להשתמש ב-Lighthouse כדי לזהות הזדמנויות ברורות לאופטימיזציה של CRP, ולאחר מכן להטמיע את הקוד באמצעות Navigation Timing API כדי לעקוב אחרי הביצועים של האפליקציה בשטח.

בדיקת דף באמצעות Lighthouse

Lighthouse הוא כלי לבדיקת אפליקציות אינטרנט שמריץ סדרה של בדיקות בדף נתון, ולאחר מכן מציג את התוצאות של הדף בדוח מאוחד. אפשר להריץ את Lighthouse בתור תוסף ל-Chrome או מודול NPM, וזה שימושי לשילוב של Lighthouse עם מערכות אינטגרציה רציפה (CI).

כדי להתחיל, כדאי לקרוא את המאמר ביקורת של אפליקציות אינטרנט באמצעות Lighthouse.

כשמריצים את Lighthouse כתוסף ל-Chrome, תוצאות ה-CRP של הדף נראות כמו בצילום המסך הבא.

ביקורות CRP של Lighthouse

מידע נוסף על התוצאות של הביקורת הזו זמין במאמר שרשראות בקשות קריטיות.

השילוב של ממשק ה-API של תזמון הניווט ושל אירועים אחרים בדפדפן שנוצרים בזמן טעינת הדף מאפשר לתעד ולתעד את הביצועים של ה-CRP בפועל בכל דף.

תזמון הניווט

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

אז מה המשמעות של חותמות הזמן האלה?

  • domLoading: זוהי חותמת הזמן ההתחלתית של התהליך כולו, הדפדפן עומד להתחיל לנתח את הבייטים הראשונים שהתקבלו במסמך ה-HTML.
  • domInteractive: מציין את הנקודה שבה הדפדפן סיים לנתח את כל בניית ה-HTML וה-DOM.
  • domContentLoaded: מציין את הנקודה שבה גם ה-DOM מוכן וגם אין גיליונות סגנונות שחוסמים את ביצוע ה-JavaScript – כלומר, עכשיו אנחנו יכולים (לפי תיאוריה) ליצור את עץ הרינדור.
    • הרבה מסגרות JavaScript מחכות לאירוע הזה לפני שהן מתחילות לבצע את הלוגיקה שלהן. לכן הדפדפן מתעד את חותמות הזמן EventStart ו-EventEnd כדי לאפשר לנו לעקוב אחרי משך הזמן של הביצוע.
  • domComplete: כפי שרואים מהשם, כל העיבוד הושלם וכל המשאבים בדף (תמונות וכו') הועברו. במילים אחרות, גלגל הטעינה הפסיק להסתובב.
  • loadEvent: בשלב האחרון בכל טעינת דף, הדפדפן מפעיל אירוע onload שיכול להפעיל לוגיקה נוספת של האפליקציה.

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

  • domInteractive מסמנת את המועד שבו DOM מוכן.
  • בדרך כלל, האירוע domContentLoaded מסמנים את המצב שבו גם ה-DOM וגם ה-CSSOM מוכנים.
    • אם אין מנתח שחוסם את JavaScript, אז DOMContentLoaded יופעל מיד אחרי domInteractive.
  • domComplete מסמן כשהדף וכל משאבי המשנה שלו מוכנים.
<!DOCTYPE html>
<html>
  <head>
    <title>Critical Path: Measure</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link href="style.css" rel="stylesheet" />
    <script>
      function measureCRP() {
        var t = window.performance.timing,
          interactive = t.domInteractive - t.domLoading,
          dcl = t.domContentLoadedEventStart - t.domLoading,
          complete = t.domComplete - t.domLoading;
        var stats = document.createElement('p');
        stats.textContent =
          'interactive: ' +
          interactive +
          'ms, ' +
          'dcl: ' +
          dcl +
          'ms, complete: ' +
          complete +
          'ms';
        document.body.appendChild(stats);
      }
    </script>
  </head>
  <body onload="measureCRP()">
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="awesome-photo.jpg" /></div>
  </body>
</html>

רוצים לנסות?

הדוגמה הקודמת עשויה להיראות מרתיעה במבט ראשון, אבל בפועל היא פשוטה למדי. ה-API של תזמון הניווט מתעד את כל חותמות הזמן הרלוונטיות והקוד שלנו ממתין להפעלה של האירוע onload. חשוב לזכור שהאירוע onload מופעל אחרי domInteractive, domContentLoaded ו-domComplete – ומחשב את ההפרש בין חותמות הזמן השונות.

הדגמה של NavTiming

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

מה לגבי כלי הפיתוח?

למרות שבמסמכים האלה נעשה שימוש לפעמים בחלונית של רשת כלי הפיתוח ל-Chrome כדי להדגים מושגים של CRP, כלי הפיתוח לא מתאימים במיוחד למדידות CRP כי אין בו מנגנון מובנה לבידוד משאבים קריטיים. כדי לזהות משאבים כאלה, כדאי להריץ ביקורת של Lighthouse.

משוב