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

Ilya Grigorik
Ilya Grigorik

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

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

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

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

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

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

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

ביקורות CRP של Lighthouse

למידע נוסף על תוצאות הביקורת, קראו את המאמר Critical Request Chains (שרשראות של בקשות קריטיות).

השילוב של 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 – ומחשב את ההפרש בין חותמות הזמן השונות.

הדגמה של תזמון ניווט

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

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

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

משוב