שימוש בחלונית Performance בכלי הפיתוח ל-Chrome כדי ליצור פרופיל של אפליקציות Angular

Andrés Olivares
Andrés Olivares
Pawel Kozlowski
Pawel Kozlowski

מסגרות אינטרנט כמו Angular,‏ React,‏ Vue ו-Svelte מקלות על כתיבה ותחזוקה של אפליקציות אינטרנט מורכבות בהיקף רחב.

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

לדוגמה, כשמבצעים פרופיל של אפליקציית Angular באמצעות החלונית Performance בכלי הפיתוח, מוצגות התוצאות הבאות:

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

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

אחת הסיבות הנפוצות לכתיבת מסגרות ומופשטים היא הטמעה של תוספים משלהם ל-DevTools, שמציגים נתוני פרופילים במונחים של מושגי המסגרת. הכלים האלה שימושיים מאוד כשמבצעים ניפוי באגים ופרופיל של אפליקציות שנבנו באמצעות מסגרת ספציפית. עם זאת, ברוב המקרים תצטרכו ליצור קורלציה בין נתוני המסגרת בכלי ליצירת פרופילים של המסגרת לבין מידע על זמן הריצה של הדפדפן בחלונית Performance בכלי הפיתוח. הצגת שני מקורות הנתונים האלה בנפרד בכלים עצמאיים מקשה על זיהוי צווארי בקבוק ועל תיקונם, במיוחד כשהאפליקציה הופכת למורכבת יותר. דוגמה להמחשה חזותית של פרופיל בכלי Angular DevTools Profiler:

הכרטיסייה Profiler בכלי Angular DevTools, שבה מוצג תרשים להבה של זמן הריצה של אפליקציית Angular. לפריטים שמרכיבים את תרשים הלהבה יש תוויות שקל לקרוא אותן והן מזכירות שמות של רכיבי Angular.
Angular DevTools Profiler.

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

לכן, שיתפנו פעולה עם צוות Angular כדי להציג נתוני זמן ריצה של Angular ישירות בחלונית Performance באמצעות ה-API להרחבת חלונית הביצועים. בפוסט הזה נסביר מה ה-API יכול לעשות ואיך הוא שימש במסגרת Angular כדי להשיג את זה. ההטמעה יכולה לשמש כדוגמה למסגרות ולמופשטים אחרים שרוצים לשפר את חוויית המפתחים שלהם על ידי הפעלת הכלים שלהם ועזרה למפתחים שמשתמשים בכלי הפיתוח ל-Chrome.

מה זה Performance panel extensibility API?

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

  • ‫User Timing API
  • console.timeStamp API

‫User Timing API

אפשר להשתמש בתווים performance.mark ו-performance.measure כדי להוסיף את הערכים כך:


// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();

// ... later in your code

performance.measure("Component rendering", {
  start: renderStart,
  detail: {
    devtools: {
      dataType: "track-entry",
      track: "Components",
      color: "secondary",
      properties: [
        ["Render reason", "Props changed"],
        ["Priority", "low"]
      ],
    }
  }
});

כתוצאה מכך, רצועת הרכיבים תתווסף לציר הזמן עם המדידה:

תצוגת המעקב בחלונית הביצועים. הוא מתמקד בטראק המותאם אישית המורחב שנקרא 'רכיבים' ומכיל מדד שנקרא 'עיבוד רכיבים'
טראק בהתאמה אישית בחלונית הביצועים.

ה-API הזה מאפשר להוסיף את הרשומות למאגר הזמני של ציר הזמן של הביצועים, וגם להציג אותן בממשק המשתמש של חלונית הביצועים ב-DevTools.

מידע נוסף על ה-API הזה ועל אובייקט devtools זמין במסמכי התיעוד.

console.timeStamp API

ה-API הזה הוא חלופה קלה ל-User Timing API. בדוגמה הקודמת, יכול להיות שיהיו לכם:


// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();

// ... later in your code

console.timeStamp(
"Component rendering",
/* start time */ renderStart,
/* end time (current time) */ undefined,
/* track name */ "Components",
 /* track group name */ undefined,
 /* color */ "secondary"
);

ה-API הזה מספק שיטה עם ביצועים גבוהים להטמעת אפליקציות: בניגוד לחלופה של User Timing API, הוא לא יוצר נתונים שנשמרים במאגר זמני. ממשק ה-API הזה מוסיף נתונים רק לחלונית **Performance** בכלי הפיתוח. כלומר, כשהכלי לא מקליט מעקב, הקריאות ל-API לא מבצעות פעולה (no-ops), ולכן הוא מהיר יותר ומתאים לנקודות חמות שרגישות לביצועים. הבחירה להשתמש בארגומנטים מיקומיים במקום באובייקט שמכיל את כל פרמטרי ההתאמה האישית נועדה גם לשמור על ממשק ה-API קל משקל ככל האפשר.

במסמכי התיעוד מוסבר איך להשתמש ב-console.timeStamp כדי להרחיב את חלונית הביצועים, ומהם הפרמטרים שאפשר להעביר.

איך Angular משלבת את DevTools Extensibility API

נבדוק איך צוות Angular השתמש ב-API להרחבה כדי לבצע שילוב עם כלי הפיתוח ל-Chrome.

איך נמנעים מתקורה באמצעות console.timestamp

החל מגרסה 20, אפשר להשתמש ב-API להרחבת החלונית Performance כדי להגדיר את Angular. רמת הפירוט הרצויה של נתוני הביצועים בכלי הפיתוח מחייבת API מהיר, ולכן בקשת המשיכה (60217) שנוספה למכשור בחרה להשתמש ב-API של console.timeStamp. כך נמנעת השפעה על ביצועי זמן הריצה של האפליקציה כתוצאה מהתקורה הפוטנציאלית של פרופיל ה-API.

נתונים שנאספו באמצעות כלי מדידה

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

  • אתחול של אפליקציות ורכיבים.
  • יצירה ועדכונים של רכיבים.
  • הפעלה של פונקציות event listener ושל lifecycle hooks.
  • עוד הרבה אחרים (לדוגמה, יצירה של רכיבים דינמיים ורינדור של בלוקים מושהים).

קודי צבעים

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

בצילום המסך הבא אפשר לראות איך זה מוביל לנקודות כניסה (כמו זיהוי שינויים ועיבוד רכיבים) בכחול, קוד שנוצר בסגול וקוד TypeScript (כמו מאזיני אירועים ו-hooks) שמוצג בירוק.

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

שימו לב: הארגומנט color שמועבר אל ה-API הוא לא ערך צבע CSS, אלא אסימון סמנטי שממופה לצבע שתואם לממשק המשתמש של כלי הפיתוח. הערכים האפשריים הם primary,‏ secondary ו-tertiary, עם הווריאציות שלהם -dark ו--light, וגם צבע error.

טראקים

בזמן הכתיבה, כל נתוני זמן הריצה של Angular מתווספים לאותו מסלול (מסומן בתווית '🅰️ Angular'). עם זאת, אפשר להוסיף כמה טראקים ל-Trace ואפילו לקבץ אותם. לדוגמה, אם נתונות הקריאות הבאות ל-API‏ console.timeStamp:

console.timeStamp("Component 1", componentStart1, componentEnd1, "Components", "Client", "primary");
console.timeStamp("Component 2", componentStart2, componentEnd2, "Components", "Client", "primary");
console.timeStamp("Hook 1", hookStart, hookEnd, "Hooks", "Client", "primary");
console.timeStamp("Fetch data base", fetchStart, fetchEnd, "Server", "primary");

הנתונים יסודרו במסלולים באופן הבא:

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

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

למה זה חשוב למפתחי Angular

המטרה של השילוב הישיר הזה היא לספק חוויה אינטואיטיבית ומקיפה יותר של ניתוח ביצועים. הצגת נתוני הביצועים הפנימיים של Angular ישירות בחלונית **Performance** מאפשרת למפתחים:

  • שיפור הנראות: הצגת אירועי ביצועים ספציפיים ל-Angular, כמו עיבוד רכיבים, מחזורי זיהוי שינויים ועוד, בציר הזמן הרחב יותר של הדפדפן.
  • הבנה משופרת: מידע עשיר בהקשר על התהליכים הפנימיים של Angular, שיעזור לכם לזהות צווארי בקבוק בביצועים בצורה יעילה יותר.

הפעלת השילוב

השימוש ב-Extensibility API זמין באופן רשמי בגרסאות פיתוח החל מגרסה 20 של Angular. כדי להפעיל אותו, צריך להריץ את כלי השירות הגלובלי `ng.enableProfiling()` באפליקציה או במסוף כלי הפיתוח. מידע נוסף על השילוב זמין ב[מסמכי Angular](https://angular.dev/best-practices/profiling-with-chrome-devtools)

שיקולים נוספים

יש כמה שיקולים חשובים שכדאי לקחת בחשבון.

מפות מקור וקוד מוקטן:

מפות מקור הן כלי נפוץ שמטרתו לגשר על הפער בין קוד מאוגד או מוקטן לבין הקוד המקורי, ולכן...

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

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

תוספים לכלי הפיתוח ל-Chrome:

תוספים ל-Chrome שמשתמשים ב-DevTools API הם כלי נפוץ להרחבת כלי הפיתוח.

האם פרופילים ייעודיים (לדוגמה, תוספים של כלי הפיתוח ל-Chrome) מיותרים או לא מומלצים עכשיו כשה-API הזה זמין?

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

הדרך קדימה

הפוטנציאל של Extensibility API.

עבודה עם יותר מסגרות והפשטות

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

גרסאות לסביבת ייצור

אחת המטרות של ה-API הזה היא לעבוד עם מסגרות וספקי הפשטה באופן כללי, כדי לאמץ ולאפשר את המכשור בגרסאות ייצור. הדבר יכול להשפיע באופן משמעותי על הביצועים של האפליקציות שפותחו באמצעות ההפשטות האלה, כי המפתחים יוכלו ליצור פרופיל של האפליקציה כפי שהמשתמשים חווים אותה. אנחנו מאמינים ש-console.timeStamp API מאפשר להשיג את זה, בהתחשב במהירות שלו ובעלויות התקורה הנמוכות שלו. עם זאת, בשלב הזה, צוותי הפיתוח של המסגרות עדיין בודקים את ה-API ומנסים להבין אילו סוגים של מכשירי מדידה הם יותר ניתנים להרחבה ושימושיים למפתחים.