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

נראה בסדר, לא? אבל בפועל – עם עשרות אלפי אייטמים הביצועים של זה היו נוראיים. תראו למשל מה קורה כשאני מריץ את זה על 200,000 תאריכים:

החשוד המרכזי – פונקציה Built-In של JavaScript?!
אין ספק – ה-Profiler הצביע ישר על toLocaleString
כאשם המרכזי. אבל איך זה הגיוני? הרי זו פונקציה מובנית של JavaScript, הם בטח כתבו אותה בצורה הכי יעילה שיש, לא?
אחרי הרבה חפירות ב-Google ושיחות רומנטיות עם ChatGPT שלא העלו יותר מידי, החלטתי לבדוק את זה בעצמי.
ניסוי ראשון: לקרוא ישירות ל-Intl.DateTimeFormat
בגלל ש-toLocaleString
משתמש מאחורי הקלעים ב-Intl.DateTimeFormat
, הרעיון הראשון שחשבתי עליו היה לוותר על האבסטרקציה הזאת ולגשת לאובייקט הזה ישירות. כלומר, אולי אם אני פשוט אצור מופע אחד של Intl.DateTimeFormat
ואשתמש בו שוב ושוב, זה יהיה יותר מהיר?

והתוצאה? שיפור ביצועים מטורף, גם כשבדקתי את זה על מיליון פריטים! 🚀

אבל למה לעצור כאן? אולי אפשר לשפר את זה עוד?
בשלב הזה תהיתי – מה יקרה אם בכלל אוותר על Intl
ואכתוב את הפורמט בעצמי? זה הרי פורמט די פשוט:

והתוצאה? שיפור ביצועים משמעותי אפילו יותר!

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

גם כאן, שימוש חוזר ב-Intl.NumberFormat
משפר משמעותית את הביצועים, אבל הכי מהר? פשוט לוותר עליו ולכתוב קוד מותאם אישית.
מסקנות: איך לייצר שיפור ביצועים עם פורמטינג ב-JavaScript
- עובדים עם כמות גדולה של נתונים? צרו מופע
Intl
אחד בלבד ותשתמשו בו שוב ושוב. - אם אפשר, כדאי לוותר על פונקציות עיצוב גנריות, ולכתוב קוד שמתאים בדיוק למה שאתם צריכים.
- תמיד תבצעו פרופיילינג לפני שאתם מניחים שפונקציה מובנית מספיק מהירה – לפעמים היא יכולה להיות צוואר בקבוק רציני.
🚀 לסיכום: קוד קריא זה חשוב, אבל שימוש ״על עיוור״ בפונקציות גנריות יכול בקלות לפגוע בביצועים, בלי שתשימו לב!
זאת היתה עוד צלילה עמוקה לאופטימיזציה של JavaScript. במאמר הבא, נציג עוד יכולת תמימה למראה, שבכמות גדולה של נתונים יכולה להוביל לביצועים בעייתיים… 🙈 הישארו מעודכנים!
👈 לקריאת המאמר הקודם בסדרה על שיפור ביצועים בעבודה עם מערכים ורשימות.
מאמרים קשורים
The Dark Side of JS Formatting
Are you aware of this Regex pitfall
Think One WebWorker is Enough? Think Again