ביצוע קל ופשוט של ביצועי האינטרנט - מהדורת 2018 של Google I/O

ב-Google IO 2018 הצגנו סיכום של הכלים, הספריות וטכניקות האופטימיזציה, שמאפשרים לשפר את הביצועים באינטרנט בקלות רבה יותר. כאן אנחנו מסבירים להם על השימוש באפליקציה של תיאטרון Oodles. בנוסף, אנחנו מדברים על הניסויים שלנו, עם תחזיות של טעינה חזויה ועל היוזמה החדשה של Guess.js.

Addy Osmani
Addy Osmani
Ewa Gasperowicz

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

הצורך בביצועים

האינטרנט הולך וגדל מדי שנה. כשבודקים את מצב האינטרנט אפשר לראות חציון של דף בנייד במשקל של כ-1.5MB, כשרובו הוא JavaScript ותמונות.

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

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

פירמידה של היררכיית חוויית משתמש
איור 1. עד כמה המהירות חשובה למשתמשים? (Speed Matters, כרך 3)

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

Lighthouse – בסיס לתהליך עבודה של ביצועים

Lighthouse הוא חלק מכלי הפיתוח ל-Chrome, שמאפשר לערוך ביקורת של האתר ונותן לכם רמזים לשיפור.

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

ביקורות חדשות במסגרת Lighthouse
איור 2. ביקורות חדשות במסגרת Lighthouse

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

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

דוח Lighthouse לאפליקציית Oodles
איור 3. דוח Lighthouse לאפליקציית Oodles

הביצועים הראשוניים של האפליקציה שלנו כפי שהם מופיעים בדוח Lighthouse היו די גרועים. ברשת 3G, המשתמש היה צריך להמתין 15 שניות עד להצגת התמונה המשמעותית הראשונה, או כדי שהאפליקציה תהפוך לאינטראקטיבית. Lighthouse הדגיש המון בעיות באתר שלנו, וציון הביצועים הכולל של 23 הראה בדיוק את זה.

הדף משוקלל כ-3.4MB – היינו צריכים נואשות להוריד מעט שומן.

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

הזדמנויות לאופטימיזציה של הביצועים

הסרת משאבים לא נחוצים

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

רווחים מהקטנה
איור 4. הקטנה ודחיסה של JavaScript ו-CSS

ההזדמנות הזו מודגשת ב-Lighthouse בביקורת שירותי CSS ו-JavaScript בלתי מזוהים. השתמשנו בחבילה באינטרנט לתהליך ה-build, אז כדי לבצע הקטנה השתמשנו בפלאגין של Uglify JS.

פעולת ההקטנה היא משימה נפוצה, ולכן אתם צריכים למצוא פתרון מוכן לכל תהליך build שבו אתם משתמשים.

עוד ביקורת שימושית באזור הזה היא Enable text compression (הפעלה של דחיסת טקסט). אין סיבה לשלוח קבצים לא דחוסים, ורוב ה-CDN תומכים באפשרות הזו בימים אלה.

השתמשנו באירוח ב-Firebase כדי לארח את הקוד שלנו, ו-Firebase מאפשר באמצעות gzip כברירת מחדל, כך שבזכות אירוח הקוד שלנו ב-CDN סביר, קיבלנו את זה בחינם.

gzip היא דרך פופולרית מאוד לדחיסת נתונים, אבל גם מנגנונים אחרים כמו Zopfli ו-Brotli מקבלים נפח משיכה. Brotli נהנים מתמיכה ברוב הדפדפנים, ואפשר להשתמש בקובץ בינארי כדי לדחוס מראש את הנכסים לפני שליחתם לשרת.

שימוש במדיניות מטמון יעילה

השלב הבא היה להבטיח שאנחנו לא שולחים משאבים פעמיים אם אין בהם צורך.

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

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

הסרת קוד שלא נמצא בשימוש

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

כיסוי קוד בכלי הפיתוח
איור 5. בודקים את כיסוי הקוד

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

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

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

מערכת Lighthouse זיהתה את הבעיה הזו גם בבדיקת כללי CSS שלא נעשה בהם שימוש. היא הציגה חיסכון אפשרי של יותר מ-400kb. חזרנו לקוד שלנו והסרנו גם את ה-JavaScript וגם את החלק של CSS מהספרייה.

אם נשחרר את מתאם ה-MVC, הסגנונות שלנו ירדו ל-10KB
איור 6. אם נשחרר את מתאם ה-MVC, הסגנונות שלנו ירדו ל-10KB!

כתוצאה מכך, חבילת ה-CSS שלנו הצטמצמה פי 20, וזה דבר די טוב תמורת התחייבות קטנה של שתי שורות.

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

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

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

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

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

הימנעות ממטענים ייעודיים (payloads) עצומים ברשת

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

מערכת Lighthouse זיהתה בעיה בחלק ממטענים ייעודיים (payloads) של הרשת שלנו באמצעות הביקורת Enormous Network payload.

זיהוי מטענים ייעודיים (payloads) עצומים ברשת
איור 8. זיהוי מטענים ייעודיים (payloads) עצומים ברשת

כאן ראינו שיש לנו קוד בשווי של יותר מ-3MB שנשלח למטה – וזה הרבה מאוד, במיוחד בנייד.

בחלק העליון של הרשימה, Lighthouse הדגיש שיש לנו חבילה של ספקי JavaScript בנפח של 2MB בקוד לא דחוס. זוהי גם בעיה שמסומנת ב-webpack.

כפי שנאמר: הבקשה המהירה ביותר היא זו שלא נשלחת.

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

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

ביקורת על חבילת JavaScript
איור 9. ביקורת של חבילת JavaScript

התחלנו עם כלי לניתוח חבילות Webpack, שהודיע לנו שאנחנו כוללים תלות שנקראת unicode, שהייתה 1.6MB ב-JavaScript מנותח, אז הרבה מאוד.

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

אחר כך עברנו לכלי אחר, BundlePhobia. זהו כלי שמאפשר להזין את השם של כל חבילת NPM ולראות בפועל את הגודל המוקטן שלה ב-gzip. מצאנו חלופה נחמדה למודול החילוף שבו השתמשנו, ששקל רק 2.2kb, אז החלפנו אותו.

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

ראינו שיפור של 65% באופן כללי, לאחר הבאת הגודל של החבילות האלה כ-gzip והקטנה. וגילינו שכדאי מאוד לעשות את זה כתהליך.

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

קיצור זמן האתחול של JavaScript עם פיצול קוד

למטענים ייעודיים (payloads) גדולים ברשת יכולה להיות השפעה משמעותית על האפליקציה שלנו, אבל יש דבר נוסף שיכול להשפיע בצורה משמעותית מאוד והוא JavaScript.

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

כך דפדפן מעבד JavaScript.

עיבוד JavaScript
איור 10. עיבוד JavaScript

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

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

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

זמן אתחול של JavaScript
איור 11. ביקורת על זמן האתחול של JavaScript

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

אחת השיטות לעקוף את זה היא שימוש בפיצול קוד.

פיצול קוד הוא כמו פיצה

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

ניתן להחיל פיצול קוד ברמת המסלול או ברמת הרכיב. הוא עובד מצוין עם React ו-React Loadable, Vue.js, Angular, Polymer, Preact ועוד כמה ספריות אחרות.

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

פיצול קוד באמצעות ייבוא דינמי
איור 13. פיצול קוד באמצעות ייבוא דינמי

ההשפעה הזו התכווצה את גודל החבילות שלנו, אבל גם הצליחה לקצר את זמן ההפעלה של JavaScript. מהירות האפליקציה ירדה ל-0.78 שניות, כך שהאפליקציה מהירה יותר ב-56%.

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

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

לבצע אופטימיזציה של תמונות

בדיחת ביצועים בטעינת תמונה

אנחנו משתמשים בהרבה תמונות באפליקציית Oodle. לצערנו, ב-Lighthouse היו הרבה פחות התלהבות מאיתנו. למעשה, לא הצלחנו בכל שלוש הביקורות שקשורות לתמונות.

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

בדיקת תמונות
איור 14. בדיקות של תמונות Lighthouse

התחלנו באופטימיזציה של התמונות שלנו.

בסבב אופטימיזציה חד-פעמי, תוכלו להשתמש בכלים ויזואליים כמו ImageOptim או XNConvert.

גישה אוטומטית יותר היא להוסיף שלב לאופטימיזציה של תמונות לתהליך ה-build, עם ספריות כמו imagemin.

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

אם אתם לא רוצים לעשות את זה בגלל בעיות בעלויות או בזמן האחזור, פרויקטים כמו Thumbor או Imageflow מציעים חלופות באירוח עצמי.

לפני ואחרי האופטימיזציה
איור 15. לפני ואחרי האופטימיזציה

קובץ ה-PNG של הרקע שלנו סומן ב-webpack כגדול, וזהו אכן גדול. אחרי שהגדרנו אותו בצורה נכונה לאזור התצוגה והרצתנו אותו באמצעות ImageOptim, ירדנו ל-100kb, שהוא מספיק.

חזרה על הפעולות האלה במספר תמונות באתר שלנו אפשרה לנו להפחית משמעותית את המשקל הכולל של הדף.

שימוש בפורמט הנכון לתוכן מונפש

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

באפליקציית Oodle השתמשנו בקובץ GIF כרצף של הקדמה בדף הבית. על פי Lighthouse, אפשר לחסוך יותר מ-7MB על ידי מעבר לפורמט וידאו יעיל יותר. הקליפ שלנו קיבל משקל של כ-7.3MB, הרבה יותר מדי לכל אתר סביר, לכן במקום זאת הפכנו אותו לרכיב וידאו עם שני קובצי מקור - mp4 ו-WebM לתמיכה רחבה יותר בדפדפנים.

החלפת קובצי GIF מונפשים בסרטון
איור 16. החלפת קובצי GIF מונפשים בסרטון

השתמשנו בכלי FFmpeg כדי להמיר את קובץ ה-GIF של האנימציה לקובץ mp4. פורמט WebM מציע לך חיסכון גדול יותר - ממשק ה-API של ImageOptim יכול לבצע המרה כזו.

ffmpeg -i animation.gif -b:v 0 -crf 40 -vf scale=600:-1 video.mp4

הודות להמרה הזו הצלחנו לחסוך יותר מ-80% מהמשקל הכולל שלנו. זה גרם לנו למהירות 1MB.

עדיין, 1MB הוא משאב גדול שדרוש כדי לדחוף את החוטים כלפי מטה, במיוחד למשתמשים עם רוחב פס מוגבל. למזלנו, יכולנו להשתמש ב-Effective Type API כדי להבין שרוחב הפס שלהם איטי, ותנו במקום זאת קובץ JPEG קטן יותר.

הממשק הזה משתמש בערכים האפקטיביים של הלוך ושוב ובערכי ירידה כדי להעריך את סוג הרשת שבו המשתמש משתמש. הוא פשוט מחזיר מחרוזת, 2G איטי, 2G, 3G או 4G. כך שבהתאם לערך הזה, אם המשתמש נמצא מתחת ל-4G, נוכל להחליף את רכיב הווידאו בתמונה.

if (navigator.connection.effectiveType) { ... }

זה מפחית מעט מהחוויה, אבל לפחות אפשר להשתמש באתר בחיבור איטי.

טעינה מדורגת של תמונות שלא מופיעות במסך

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

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

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

<!-- Import library -->
import lazysizes from 'lazysizes'  <!-- or -->
<script src="lazysizes.min.js"></script>

<!-- Use it -->

<img data-src="image.jpg" class="lazyload"/>
<img class="lazyload"
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w"/>

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

אחרי השינוי הזה, התמונות שלנו יאוחזרו על פי דרישה. אם תרצו להתעמק בנושא הזה, תוכלו לעיין ב-images.guide – משאב שימושי ומקיף מאוד.

איך עוזרים לדפדפן לספק משאבים חיוניים בשלב מוקדם

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

משהו שיכול להועיל לנו, ככותבי הדף, להודיע לדפדפן מה באמת חשוב לנו. למרבה המזל, בשנים האחרונות ספקים של דפדפנים הוסיפו כמה תכונות כדי לעזור לנו לעשות זאת, כמו רמזים למשאבים כמו link rel=preconnect, או preload או prefetch.

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

בואו נראה איך Lighthouse ידריך אותנו בפועל לגבי שימוש יעיל בחלק מהתכונות האלה.

הדבר הראשון ש-Lighthouse מבקש מאיתנו לעשות הוא להימנע מנסיעות הלוך ושוב ויקרות לכל מקור.

הימנעות מכמה נסיעות הלוך ושוב ויקרות לכל מקור
איור 17. יש להימנע מכמה נסיעות הלוך ושוב ויקרות לכל נקודת מוצא

כשמדובר באפליקציית Oodle, אנחנו למעשה משתמשים ב-Google Fonts. בכל פעם שמשחררים גיליון סגנונות של Google Font בדף, הוא יקשר עד שני תת-דומיינים. לפי הנתונים של Lighthouse, אם הצלחנו לחמם את החיבור, נוכל לחסוך עד 300 אלפיות השנייה בזמן החיבור הראשוני.

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

יכולה להיות לכך השפעה משמעותית מאוד, במיוחד באובייקטים כמו Google Fonts, שבהם מתארח ה-CSS של פני הגופנים ב-googleapis.com, ומשאבי הגופנים שמתארחים ב-Gstatic. ביצענו את האופטימיזציה הזו וצמצמנו כמה מאות אלפיות השנייה.

המידע הבא מ-Lighthouse הוא שאנחנו טוענים מראש בקשות מרכזיות.

טעינה מראש של בקשות עיקריות
איור 18. טעינה מראש של בקשות עיקריות

<link rel=preload> הוא שירות חזק מאוד, הוא מודיע לדפדפן שנדרש משאב כחלק מהניווט הנוכחי, ומנסה לגרום לדפדפן לאחזר אותו בהקדם האפשרי.

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

טעינה מראש בגופן אינטרנט נראית כך, כאשר מציינים rel=preload, מעבירים ב-as את סוג הגופן, ולאחר מכן מציינים את סוג הגופן שאתם מנסים לטעון בו, כמו woff2.

ההשפעה הזאת על הדף יכולה להיות די חמורה.

ההשפעה של טעינה מראש של משאבים
איור 19. ההשפעה של טעינה מראש של משאבים

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

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

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

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

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

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

ניסיוני: רמזים לקביעת עדיפות

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

הגדרת עדיפות לתוכן שמוצג בהתחלה
איור 20. טיפים לעדיפות

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

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

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

הגדרת עדיפות לתוכן שמוצג בהתחלה
איור 21. הגדרת עדיפות לתוכן שמוצג בהתחלה

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

אנחנו מקווים להשיק את התכונה הזו ל-Canary בעוד כמה שבועות, אז כדאי לחכות.

להשתמש באסטרטגיה של טעינת גופנים לאינטרנט.

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

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

הימנעות מטקסט מוסתר בזמן שגופנים באינטרנט נטענים
איור 22. נמנעים מטקסט מוסתר בזמן שגופנים באינטרנט נטענים

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

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

    @font-face {
      font-family: 'Montserrat';
      font-style: normal;
      font-display: swap;
      font-weight: 400;
      src: local('Montserrat Regular'), local('Montserrat-Regular'),
          /* Chrome 26+, Opera 23+, Firefox 39+ */
          url('montserrat-v12-latin-regular.woff2') format('woff2'),
            /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
          url('montserrat-v12-latin-regular.woff') format('woff');
    }

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

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

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

תוצאה של תצוגת הגופן
איור 23. תוצאה של תצוגת הגופן

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

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

הפחתת סקריפטים שחוסמים את העיבוד

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

ברצועת ציר הזמן של Lighthouse אפשר לראות שבמהלך השניות הראשונות האלה, כשכל המשאבים נטענים, המשתמש לא יכול לראות שום תוכן.

הפחתת ההזדמנות של גיליונות סגנונות החוסמים עיבוד
איור 24. הפחתת ההזדמנות של גיליונות סגנונות שחוסמים את העיבוד

הורדה ועיבוד של גיליונות סגנונות חיצוניים מונעים תהליך העיבוד שלנו.

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

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

במקרה שלנו, השתמשנו במודול NPM שנקרא Critical כדי להטמיע את התוכן הקריטי ב-index.html במהלך שלב ה-build.

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

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

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

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

התוצאה

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

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

ביצועים חזויים – חוויות משתמש מבוססות-נתונים

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

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

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

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

חבילות מבוססות-נתונים לאפליקציות אינטרנט
איור 25. קיבוץ מבוסס-נתונים לאפליקציות אינטרנט

כדי להקל על הניסוי, אנחנו שמחים להכריז על יוזמה חדשה שאנחנו קוראים לה Guess.js.

Guess.js
איור 26. Guess.js

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

רוצה לספר לנו מה דעתך על Guess.js?

סיכום

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

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

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

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