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

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

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

השילוב של Navigation Timing 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.

משוב