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

זה יכול להיות בעייתי, כי סוג החיבור לרשת בפועל של המשתמש לא בהכרח יהיה 3G, 4G או Wi-Fi. יכול להיות שאתם מחוברים ל-Wi-Fi של בית קפה, אבל גם לנקודה לשיתוף אינטרנט (Hotspot) סלולרית במהירות 2G.
כדי לצמצם את עלות ההעברה של JavaScript ברשת, אפשר:
- שליחה רק של הקוד שהמשתמש צריך.
- הקטנה
- משתמשים ב-UglifyJS כדי למזער קוד ES5.
- כדי להקטין את הנפח של ES2015 ואילך, משתמשים ב-babel-minify או ב-uglify-es.
- דחיסה
- הסרת קוד שלא בשימוש.
- מזהים הזדמנויות להסרת קוד או לטעינה מדורגת של קוד באמצעות רמת הכיסוי של הקוד בכלי הפיתוח.
- כדי להימנע מטרנספילציה של תכונות שכבר קיימות בדפדפנים מודרניים, השתמשו ב-babel-preset-env וב-browserlist. מפתחים מתקדמים יכולים לנתח את חבילות ה-webpack כדי לזהות הזדמנויות להסרת יחסי תלות מיותרים.
- כדי להסיר קוד, אפשר לעיין ב-tree-shaking, באופטימיזציות המתקדמות של Closure Compiler ובפלאגינים לחיתוך ספריות כמו lodash-babel-plugin או ContextReplacementPlugin של webpack לספריות כמו Moment.js.
- שמירת קוד במטמון כדי לצמצם את מספר הנסיעות ברשת.
- משתמשים בשמירה במטמון של HTTP כדי לוודא שהדפדפנים שומרים במטמון את התגובות בצורה יעילה. כדאי לקבוע את משך החיים האופטימלי של סקריפטים (max-age) ולספק אסימוני אימות (ETag) כדי להימנע מהעברת בייטים שלא השתנו.
- שמירת קובץ השירות (service worker) במטמון יכולה להפוך את האפליקציה לעמידה בפני בעיות ברשת, ולתת לכם גישה מהירה לתכונות כמו שמירת קוד V8 במטמון.
- כדאי להשתמש בשמירה במטמון לטווח ארוך כדי להימנע מאחזור מחדש של משאבים שלא השתנו. אם אתם משתמשים ב-Webpack, עיינו במאמר filename hashing.
ניתוח/הידור
אחרי ההורדה, אחת מהעלויות הגבוהות ביותר של JavaScript היא הזמן שלוקח למנוע JS לנתח/לקמפל את הקוד הזה. בכלי הפיתוח ל-Chrome, הניתוח וההידור הם חלק מהזמן הצהוב של "Scripting" בחלונית Performance.

בכרטיסיות Bottom-Up ו-Call Tree מוצגים זמני הניתוח/הקימפול המדויקים:
אבל למה זה חשוב?

אם לוקח הרבה זמן לנתח או לקמפל את הקוד, זה יכול לעכב באופן משמעותי את הזמן שבו המשתמש יכול לבצע אינטראקציה עם האתר. ככל ששולחים יותר JavaScript, כך לוקח יותר זמן לנתח ולקמפל אותו לפני שהאתר הופך לאינטראקטיבי.
בייט לבייט, לדפדפן יקר יותר לעבד JavaScript מאשר תמונה או גופן אינטרנט בגודל שווה ערך — טום דייל
בהשוואה ל-JavaScript, יש הרבה עלויות שקשורות לעיבוד תמונות בגודל שווה ערך (עדיין צריך לפענח אותן!), אבל בחומרה ממוצעת של מכשירים ניידים, סביר יותר ש-JS ישפיע לרעה על האינטראקטיביות של הדף.
כשאנחנו אומרים שהניתוח וההידור איטיים, ההקשר חשוב – אנחנו מדברים כאן על טלפונים ניידים ממוצעים. למשתמשים ממוצעים יכולים להיות טלפונים עם מעבדים ו-GPU איטיים, ללא מטמון L2/L3, ואולי אפילו עם מגבלות זיכרון.
לא תמיד יש התאמה בין יכולות הרשת ליכולות המכשיר. למשתמש עם חיבור סיבים מדהים אין בהכרח את המעבד הטוב ביותר לניתוח והערכה של JavaScript שנשלח למכשיר שלו. זה נכון גם בכיוון ההפוך: חיבור נוראי לרשת, אבל מעבד מהיר במיוחד. — Kristofer Baxter, LinkedIn
בהמשך אפשר לראות את העלות של ניתוח JavaScript לא דחוס (פשוט) בנפח של כ-1MB בחומרה מתקדמת ובחומרה פשוטה. הזמן שלוקח לנתח או לקמפל קוד בטלפונים המהירים ביותר בשוק קצר פי 2 עד 5 מהזמן שלוקח לעשות את זה בטלפונים ממוצעים.
מה לגבי אתר אמיתי, כמו CNN.com?
במכשיר iPhone 8 המתקדם, לוקח רק כ-4 שניות לנתח/לקמפל את ה-JS של CNN, בהשוואה לכ-13 שניות בטלפון ממוצע (Moto G4). זה יכול להשפיע באופן משמעותי על המהירות שבה משתמש יכול לבצע אינטראקציה מלאה עם האתר.
זה מדגיש את החשיבות של בדיקה בחומרה ממוצעת (כמו Moto G4) במקום רק בטלפון שאולי נמצא בכיס שלכם. עם זאת, ההקשר חשוב: בצעו אופטימיזציה בהתאם למכשיר ולתנאי הרשת של המשתמשים.
האם אנחנו באמת שולחים יותר מדי JavaScript? אממ, אולי :)
אם נשתמש ב-HTTP Archive (כ-500,000 האתרים המובילים) כדי לנתח את מצב ה-JavaScript בניידים, נראה שב-50% מהאתרים לוקח יותר מ-14 שניות עד שהם הופכים לאינטראקטיביים. באתרים האלה, רק הניתוח וההידור של JS נמשכים עד 4 שניות.

אם מוסיפים לזה את הזמן שלוקח לאחזר ולעבד JS ומשאבים אחרים, לא מפתיע שהמשתמשים צריכים לחכות קצת עד שהדפים מוכנים לשימוש. אנחנו בהחלט יכולים להשתפר בתחום הזה.
הסרת קוד JavaScript לא קריטי מהדפים יכולה לקצר את זמני ההעברה, להפחית את העומס על המעבד (CPU) שנובע מניתוח וקומפילציה, ולצמצם את התקורה הפוטנציאלית של הזיכרון. זה גם עוזר להפוך את הדפים לאינטראקטיביים מהר יותר.
זמן הביצוע
לא רק ניתוח והידור יכולים לעלות כסף. הרצת JavaScript (הרצת קוד אחרי ניתוח או הידור) היא אחת מהפעולות שצריכות להתבצע ב-thread הראשי. זמני ביצוע ארוכים יכולים גם לדחות את הזמן שבו משתמש יכול לבצע אינטראקציה עם האתר.

אם הסקריפט פועל במשך יותר מ-50 אלפיות השנייה, מהירות ההגעה לפונקציונליות מלאה מתעכבת בכל משך הזמן שלוקח להוריד, לקמפל ולהפעיל את ה-JS — אלכס ראסל
כדי לטפל בבעיה הזו, כדאי לחלק את ה-JavaScript לחלקים קטנים כדי למנוע את נעילת ה-thread הראשי. כדאי לבדוק אם אפשר לצמצם את כמות העבודה שמתבצעת במהלך ההפעלה.
עלויות אחרות
JavaScript יכול להשפיע על ביצועי הדף בדרכים אחרות:
- זיכרון. דפים יכולים להיראות כאילו הם קופצים או מושהים לעיתים קרובות בגלל GC (איסוף אשפה). כשהדפדפן מפנה זיכרון, הפעלת ה-JS מושהית, כך שדפדפן שאוסף אשפה לעיתים קרובות יכול להשהות את ההפעלה בתדירות גבוהה יותר ממה שהיינו רוצים. כדי למנוע קפיצות בדפים, הימנעו מדליפות זיכרון ומהפסקות תכופות של איסוף אשפה.
- בזמן הריצה, קוד JavaScript ארוך יכול לחסום את ה-main-thread ולגרום לדפים לא להגיב. חלוקת העבודה לחלקים קטנים יותר (באמצעות
requestAnimationFrame()אוrequestIdleCallback()לתזמון) יכולה לצמצם את הבעיות ברספונסיביות, וכך לשפר את מהירות התגובה לאינטראקציה באתר (INP).
תבניות להפחתת עלות ההעברה של JavaScript
כשמנסים לשמור על זמני ניתוח/הידור ושידור רשת איטיים עבור JavaScript, יש דפוסים שיכולים לעזור כמו חלוקה לחלקים מבוססת-נתיב או PRPL.
PRPL
PRPL (Push, Render, Pre-cache, Lazy-load) היא תבנית שמבצעת אופטימיזציה לאינטראקטיביות באמצעות פיצול קוד אגרסיבי וטעינה מראש מהמטמון:

בואו נראה איך זה משפיע.
אנחנו מנתחים את זמן הטעינה של אתרים פופולריים לנייד ושל Progressive Web Apps באמצעות Runtime Call Stats של V8. כפי שאפשר לראות, זמן הניתוח (מוצג בכתום) הוא חלק משמעותי מהזמן שמושקע באתרים האלה:

באתר Wego, שמשתמש ב-PRPL, מצליחים לשמור על זמן ניתוח נמוך של המסלולים, והוא הופך לאינטראקטיבי מהר מאוד. רבים מהאתרים האחרים שצוינו למעלה אימצו פיצול קוד ותקציבי ביצועים כדי לנסות להפחית את עלויות ה-JS שלהם.
אתחול הדרגתי
אתרים רבים מבצעים אופטימיזציה של החשיפה של התוכן על חשבון האינטראקטיביות. כדי להשיג עיבוד ראשוני מהיר כשיש חבילות JavaScript גדולות, המפתחים משתמשים לפעמים בעיבוד בצד השרת, ואז "משדרגים" אותו כדי לצרף גורמים מטפלים באירועים כשה-JavaScript נשלף בסופו של דבר.
חשוב להיזהר – יש לזה עלויות משלו. 1) בדרך כלל נשלחת תגובת HTML גדולה יותר שיכולה לדחות את האינטראקטיביות, 2) המשתמש עלול להישאר במצב שבו חצי מהחוויה לא יכולה להיות אינטראקטיבית עד ש-JavaScript יסיים את העיבוד.
יכול להיות שאתחול הדרגתי הוא גישה טובה יותר. שליחת דף עם פונקציונליות מינימלית (שמורכב רק מה-HTML, ה-JS וה-CSS שנדרשים לנתיב הנוכחי). ככל שמגיעים יותר משאבים, האפליקציה יכולה לבצע טעינה מדורגת ולפתוח תכונות נוספות.
השאיפה היא לטעון קוד באופן פרופורציונלי למה שמוצג. PRPL ו-Progressive Bootstrapping הם דפוסים שיכולים לעזור לכם להשיג את המטרה הזו.
מסקנות
גודל השידור הוא קריטי לרשתות חלשות. זמן הניתוח חשוב במכשירים שמוגבלים על ידי המעבד (CPU). חשוב לשמור על ערכים נמוכים.
צוותים רבים הצליחו להפחית את זמני ההעברה והניתוח/משך הזמן לקימפול של JavaScript על ידי הגדרת תקציבי ביצועים מחמירים. במאמר של אלכס ראסל, "Can You Afford It?: Real-world Web Performance Budgets" כדי לקבל הנחיות לגבי תקציבים לנייד.
אם אתם בונים אתר שמטרגט מכשירים ניידים, כדאי לפתח אותו על חומרה מייצגת, לשמור על זמני ניתוח/משך הזמן לקימפול נמוכים של JavaScript ולהגדיר תקציב ביצועים כדי לוודא שהצוות שלכם יוכל לעקוב אחר עלויות ה-JavaScript.
מידע נוסף
- Chrome Dev Summit 2017 - Modern Loading Best Practices
- ביצועי ההפעלה של JavaScript
- Solving the web performance crisis — Nolan Lawson
- האם אתם יכולים להרשות לעצמכם את זה? תקציבי ביצועים בעולם האמיתי — אלכס ראסל
- Evaluating web frameworks and libraries — Kristofer Baxter
- תוצאות הניסוי של Cloudflare עם Brotli לדחיסה (שימו לב ש-Brotli דינמי באיכות גבוהה יותר יכול לעכב את העיבוד הראשוני של הדף, אז כדאי לבדוק את זה בזהירות. במקום זאת, כדאי להשתמש בדחיסה סטטית).
- Performance Futures — Sam Saccone