ב-Codelab הזה, אפשר לשפר את הביצועים של האפליקציה הבאה באמצעות להסיר יחסי תלות שלא נחוצים או לא מנוצלים.
מדידה
תמיד כדאי למדוד קודם את ביצועי האתר הוספת אופטימיזציות.
- כדי לראות תצוגה מקדימה של האתר, לוחצים על הצגת האפליקציה. לאחר מכן לוחצים על מסך מלא .
עכשיו אפשר ללחוץ על החתלתול האהוב! של Firebase מסד הנתונים בזמן אמת הוא שנעשה בו שימוש באפליקציה הזו, ולכן הציון מתעדכן בזמן אמת, מסונכרן עם כל אדם אחר שמשתמש באפליקציה. 🐈
- מקישים על 'Control+Shift+J' (או על 'Command+Option+J' ב-Mac) כדי לפתוח את כלי הפיתוח.
- לוחצים על הכרטיסייה רשתות.
- מסמנים את התיבה Disable cache (השבתת מטמון).
- טוענים מחדש את האפליקציה.
קוד JavaScript בנפח של כמעט 1MB נשלח כדי לטעון אפליקציה פשוטה זו.
כדאי לקרוא את האזהרות על הפרויקט בכלי הפיתוח.
- לוחצים על הכרטיסייה מסוף.
- צריך לוודא שהאפשרות
Warnings
מופעלת בתפריט הנפתח של הרמות, שמופיע לצד קלט:Filter
.
- קוראים את האזהרה שמוצגת.
Firebase, שהיא אחת הספריות שבהן נעשה שימוש באפליקציה הזו, היא samartan, באמצעות הצגת אזהרה למפתחים שלא לייבא את החבילה כולה, אלא רק את הרכיבים שנעשה בהם שימוש. במילים אחרות, יש ספריות שאינן בשימוש שניתן להסיר באפליקציה הזו כדי לגרום לו להיטען מהר יותר.
יש גם מקרים שבהם נעשה שימוש בספרייה מסוימת, אבל ייתכן שיהיו חלופה פשוטה יותר. המושג של הסרה של ספריות לא נחוצות הוא נלמד בהמשך במדריך הזה.
ניתוח החבילה
באפליקציה יש שני יחסי תלות עיקריים:
- Firebase: פלטפורמה שמספקת כמה שהם שימושיים ל-iOS, ל-Android או לאפליקציות אינטרנט. כאן המיקום זמן אמת מסד נתונים משמש לאחסן ולסנכרן את המידע של כל חתלתול בזמן אמת.
- Moment.js: ספריית כלי עזר שמאפשרת
לטפל בתאריכים ב-JavaScript. תאריך הלידה של כל חתלתול שמור
מסד הנתונים של Firebase ו-
moment
משמש לחישוב הגיל שלו בשבועות.
איך רק שני יחסי תלות יכולים לתרום לגודל חבילה של כמעט 1MB? ובכן, אחת הסיבות לכך היא שלכל תלות יכולה להיות כך שיש הרבה יותר משתיים, אם כל עומק/הסתעפות "עץ" של תלות מובאת בחשבון. קל לאפליקציות להגדיל מהר יחסית אם כלולים יחסי תלות רבים.
צריך לנתח את ה-bundler כדי להבין טוב יותר מה קורה. יש כמה
כלים שונים שנוצרו על ידי הקהילה שיכולים לעזור לעשות את זה, כמו
webpack-bundle-analyzer
החבילה של הכלי הזה כבר כלולה באפליקציה בתור devDependency
.
"devDependencies": {
//...
"webpack-bundle-analyzer": "^2.13.1"
},
המשמעות היא שניתן להשתמש בו ישירות בקובץ התצורה של ה-webpack.
אפשר לייבא אותו בתחילת webpack.config.js
:
const path = require("path");
//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
עכשיו מוסיפים אותו כפלאגין בסוף הקובץ בתוך המערך plugins
:
module.exports = {
//...
plugins: [
//...
new BundleAnalyzerPlugin()
]
};
כשהאפליקציה נטענת מחדש, אמורה להופיע תצוגה של כל בחבילה במקום את האפליקציה עצמה.
לא חמוד כמו לראות כמה חתלתולים 🪄, אבל עדיין עוזר לך מאוד. כשמעבירים את העכבר מעל החבילות, אפשר לראות את הגודל שלהן לפי שלוש בדרכים שונות:
גודל נתונים סטטיסטיים | גודל לפני הקטנה או דחיסה. |
---|---|
גודל ניתוח | גודל החבילה בפועל בתוך החבילה לאחר ההרכבה. גרסה 4 של Webpack (שבה משתמשים באפליקציה הזו) מקטינה של קבצים שעברו הידור באופן אוטומטי ולכן זה קטן יותר מהנתון הסטטיסטי גודל. |
גודל קובץ Gzip | גודל החבילה לאחר שהיא דחוסה באמצעות קידוד gzip. הזה נושא מסוים מוסבר במדריך נפרד. |
בעזרת הכלי webpack-bundle-analyzer קל יותר לזהות תכנים שלא נמצאים בשימוש חבילות שאינן נחוצות שמהוות אחוז גדול מהחבילה.
הסרה של חבילות שלא נמצאות בשימוש
התצוגה החזותית מראה שהחבילה firebase
מכילה הרבה פרטים נוספים
מאשר רק מסד נתונים. היא כוללת חבילות נוספות כמו:
firestore
auth
storage
messaging
functions
אלה כל השירותים המדהימים שמסופקים על ידי Firebase (ועיינו מסמכי תיעוד אבל אף אחד מהם לא משמש באפליקציה, לכן אין סיבה לייבא את כולן.
ביטול השינויים שבוצעו ב-webpack.config.js
כדי לראות שוב את האפליקציה:
- הסרה של
BundleAnalyzerPlugin
מרשימת יישומי הפלאגין:
plugins: [
//...
new BundleAnalyzerPlugin()
];
- עכשיו מסירים את הייבוא שלא נמצא בשימוש מהחלק העליון של הקובץ:
const path = require("path");
//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
האפליקציה אמורה להיטען כרגיל עכשיו. יש לשנות את src/index.js
כדי לעדכן את
ייבוא מ-Firebase.
import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';
עכשיו כשהאפליקציה נטענת מחדש, האזהרה של כלי הפיתוח לא מוצגת. פתיחה של בחלונית רשת של כלי פיתוח מוצגת גם ירידה יפה בגודל החבילה:
הוסרו יותר ממחצית מגודל החבילה. ב-Firebase יש הרבה אפשרויות
והוא מאפשר למפתחים לכלול רק את אלה
הדרושים. באפליקציה הזו, רק firebase/database
שימש לאחסון ולסנכרון
כל הנתונים. הייבוא firebase/app
, שמגדיר את פלטפורמת ה-API עבור
כל אחד מהשירותים השונים, הוא תמיד נדרש.
גם ספריות פופולריות רבות, כמו lodash
, מאפשרות למפתחים
לייבא באופן סלקטיבי חלקים שונים של החבילות שלהם. בלי להתאמץ יותר מדי,
מתבצע עדכון של ייבוא הספריות באפליקציה כך שיכלול רק את הפריטים שנמצאים בשימוש
יכול להוביל לשיפורים משמעותיים בביצועים.
למרות שגודל החבילה הופחת קצת, אבל יש עוד הרבה יותר. לעשות את העבודה. 😈
הסרת חבילות לא נחוצות
בניגוד ל-Firebase, לא ניתן לייבא חלקים מהספרייה של moment
בתור
בקלות, אבל ייתכן שניתן יהיה להסיר אותה לחלוטין?
יום ההולדת של כל חתלתול חמוד נשמר בפורמט יוניקס (אלפיות שנייה) מסד הנתונים ב-Firebase.
חותמת זמן של תאריך ושעה מסוימים, מיוצגת באמצעות מספר אלפיות השנייה שחלפו מאז 1 בינואר 1970 00:00 לפי שעון UTC. אם הערכים הנוכחיים של הפרמטר אפשר לחשב את התאריך והשעה באותו פורמט, פונקציה קטנה סביר להניח שאפשר להרכיב את הגיל של כל חתלתול בשבועות.
כמו תמיד, מומלץ לא להעתיק ולהדביק את פרטי המעקב של הסרטונים שנמצאים כאן. צריך להתחיל ב-
מסירה את moment
מהייבוא של src/index.js
.
import firebase from 'firebase/app';
import 'firebase/database';
import * as moment from 'moment';
יש מעבד אירועים של Firebase שמטפל בשינויים בערכים במסד הנתונים שלנו:
favoritesRef.on("value", (snapshot) => { ... })
למעלה, מוסיפים פונקציה קטנה כדי לחשב את מספר השבועות תאריך נתון:
const ageInWeeks = birthDate => {
const WEEK_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 7;
const diff = Math.abs((new Date).getTime() - birthDate);
return Math.floor(diff / WEEK_IN_MILLISECONDS);
}
בפונקציה הזו, ההפרש באלפיות השנייה בין התאריך הנוכחי
השעה (new Date).getTime()
ותאריך הלידה (הארגומנט birthDate
, כבר
באלפיות שנייה) מחושב ומחלק במספר אלפיות השנייה
שבוע אחד.
לבסוף, אפשר להסיר את כל המופעים של moment
ב-event listener על ידי
שימוש בפונקציה הזו במקום:
favoritesRef.on("value", (snapshot) => { const { kitties, favorites, names, birthDates } = snapshot.val(); favoritesScores = favorites; kittiesList.innerHTML = kitties.map((kittiePic, index) => {const birthday = moment(birthDates[index]);return ` <li> <img src=${kittiePic} onclick="favKittie(${index})"> <div class="extra"> <div class="details"> <p class="name">${names[index]}</p><p class="age">${moment().diff(birthday, 'weeks')} weeks old</p><p class="age">${ageInWeeks(birthDates[index])} weeks old</p> </div> <p class="score">${favorites[index]} ❤</p> </div> </li> `}) });
טוענים מחדש את האפליקציה ובודקים שוב את החלונית רשת.
גודל החבילה שלנו הופחת ביותר מחצי.
סיכום
ב-Codelab הזה, אתם אמורים להבין היטב איך לנתח חבילה מסוימת ולמה היא כל כך שימושית כשמסירים תמונות שלא נחוצות או לא נחוצות חבילות. לפני שתתחילו לבצע אופטימיזציה של אפליקציה באמצעות השיטה הזו, חשוב לדעת שזה יכול להיות מורכב יותר .
אם רוצים להסיר ספריות שאינן בשימוש, כדאי לבדוק אילו חלקים נמצאים בשימוש ואילו חלקים לא. למראה מסתורי חבילה שנראית לא בשימוש בשום מקום, צריך לקחת צעד אחורה ולבדוק אילו יחסי תלות ברמה העליונה עשויים להזדקק לה. נסו למצוא דרך אפשרית להפריד ביניהם.
כשמדובר בהסרה של ספריות שלא נחוצות, הן עלולות להיות קצת יותר חשובות
ומסובך. חשוב לעבוד בשיתוף פעולה הדוק עם הצוות שלכם ולראות אם יש
הזדמנות לפשט חלקים מה-codebase. מתבצעת הסרה של moment
מהטיוטה הזו
יכול להיראות כאילו זה הדבר הנכון לעשות בכל פעם, אבל
אם היו אזורי זמן ולוקאלים שונים שצריך לטפל בהם? או
מה היה קורה אילו היו מניפולציות מורכבות יותר על התאריכים? דברים יכולים לקבל
קשה לביצוע מניפולציות וניתוח של תאריכים ושעות, וספריות כמו moment
ו-date-fns
מפשטים את התהליך הזה באופן משמעותי.
כל דבר הוא בזדון, וחשוב להעריך אם הדבר שווה המורכבות והמאמץ להשקת פתרון מותאם אישית במקום להסתמך על של צד שלישי.