בכנס Google IO 2018 הצגנו סיכום של כלים, ספריות ושיטות אופטימיזציה שיעזרו לכם לשפר את ביצועי האתרים בקלות. כאן נסביר עליהם באמצעות האפליקציה Oodles Theater. אנחנו גם מדברים על הניסויים שלנו בטעינה חזותית ועל היוזמה החדשה Guess.js.
השנה האחרונה הייתה עמוסה מאוד עבורנו, וניסינו להבין איך להפוך את האינטרנט למהיר יותר ולשפר את הביצועים שלו. בעקבות זאת, פיתחנו כלים, גישות וספריות חדשים שאנחנו רוצים לשתף איתכם במאמר הזה. בחלק הראשון נציג כמה שיטות אופטימיזציה שבהן השתמשנו בפועל בפיתוח אפליקציית Oodles Theater. בחלק השני נדבר על הניסויים שלנו בטעינה חזותית ועל היוזמה החדשה Guess.js.
הצורך בביצועים
האינטרנט הולך ונעשה כבד יותר מדי שנה. אם נבדוק את מצב האינטרנט נראה שדף חציוני בנייד עומד במשקל של כ-1.5MB, כשרובו הוא JavaScript ותמונות.
מספר האתרים שגדל והולך וגדל, יחד עם גורמים אחרים כמו זמן האחזור של הרשת, מגבלות על המעבד (CPU), דפוסי חסימה או קוד מיותר של צד שלישי, תורמים לחידה המורכבת של הביצועים.
רוב המשתמשים מדורגים את המהירות בראש היררכיית חוויית המשתמש של הצרכים שלהם. זה לא מפתיע, כי אי אפשר לעשות הרבה עד שהדף נגמר לטעינת. אי אפשר להפיק ערך מהדף, אי אפשר ליהנות מהאסתטיקה שלו.
אנחנו יודעים שהביצועים חשובים למשתמשים, אבל לפעמים קשה לדעת איפה כדאי להתחיל לבצע אופטימיזציה. למרבה המזל, יש כלים שיכולים לעזור לכם בתהליך.
Lighthouse – בסיס לתהליך העבודה לשיפור הביצועים
Lighthouse הוא חלק מכלי הפיתוח ל-Chrome שמאפשר לבצע ביקורת של האתר, ומספק טיפים לשיפור.
לאחרונה השקנו כמה ביקורות ביצועים חדשות שיעזרו לכם מאוד בתהליך הפיתוח היומיומי.
כדי להבין איך אפשר להפיק מהם תועלת, נשתמש בדוגמה מעשית: אפליקציית Oodles Theater. זוהי אפליקציית אינטרנט קטנה לדגמה, שבה אפשר לנסות כמה מה-Google Doodles האינטראקטיביים האהובים עלינו ואפילו לשחק במשחק או שניים.
במהלך פיתוח האפליקציה, רצינו לוודא שהביצועים שלה יהיו הכי טובים שאפשר. נקודת ההתחלה של האופטימיזציה הייתה דוח Lighthouse.
הביצועים הראשוניים של האפליקציה שלנו, כפי שאפשר לראות בדוח Lighthouse, היו די גרועים. ברשת של 3G, המשתמשים היו צריכים להמתין 15 שניות עד לציור המשמעותי הראשון, או עד שהאפליקציה תהיה אינטראקטיבית. ב-Lighthouse הוצגו המון בעיות באתר שלנו, ודירוג הביצועים הכולל של 23 משקף בדיוק את זה.
הדף היה במשקל של כ-3.4MB – היינו צריכים להוציא ממנו קצת שומן.
כך התחלנו את האתגר הראשון שלנו בנושא ביצועים: למצוא דברים שאפשר להסיר בקלות בלי להשפיע על החוויה הכוללת.
הזדמנויות לאופטימיזציה של ביצועים
הסרת משאבים מיותרים
יש כמה דברים ברורים שאפשר להסיר באופן בטוח: רווחים לבנים ותגובות.
ב-Lighthouse מודגשת ההזדמנות הזו בבדיקה של CSS ו-JavaScript ללא דחיסה. השתמשנו ב-webpack בתהליך ה-build שלנו, לכן כדי להקטין את התצוגה פשוט השתמשנו בפלאגין של Uglify JS.
אופטימיזציה לעומס נמוך היא משימה נפוצה, כך שתוכלו למצוא פתרון מוכן לכל תהליך build שבו אתם משתמשים.
ביקורת שימושית נוספת במרחב הזה היא הפעלת דחיסת טקסט. אין סיבה לשלוח קבצים לא דחוסים, ורוב שירותי ה-CDN תומכים בכך כברירת מחדל.
השתמשנו באירוח ב-Firebase כדי לארח את הקוד שלנו, ופלטפורמת Firebase מאפשרת שימוש ב-gzipping כברירת מחדל, כך שבזכות העקרון של אירוח הקוד שלנו ברשת CDN סבירה, קיבלנו אותו בחינם.
gzip היא דרך פופולרית מאוד לדחיסת נתונים, אבל גם מנגנונים אחרים כמו Zopfli ו-Brotli צוברים תאוצה. רוב הדפדפנים תומכים ב-Brotli, ואפשר להשתמש בקובץ בינארי כדי לדחוס מראש את הנכסים לפני ששולחים אותם לשרת.
שימוש במדיניות מטמון יעילה
השלב הבא היה להבטיח שלא נשלח משאבים פעמיים אם אין צורך.
הביקורת מדיניות מטמון לא יעילה ב-Lighthouse עזרה לנו להבין שאנחנו יכולים לבצע אופטימיזציה של אסטרטגיות האחסון במטמון כדי להשיג בדיוק את זה. הגדרנו כותרת תפוגה של max-age בשרת שלנו כדי לוודא שבביקור חוזר המשתמש יוכל לעשות שימוש חוזר במשאבים שהורד בעבר.
מומלץ לשמור במטמון כמה שיותר משאבים בצורה מאובטחת ככל האפשר למשך זמן רב ככל האפשר, ולספק אסימוני אימות לצורך אימות מחדש יעיל של המשאבים שעודכנו.
הסרת קוד שלא בשימוש
עד עכשיו הסרנו את החלקים הברורים של ההורדה המיותרת, אבל מה לגבי החלקים הפחות ברורים? לדוגמה, קוד שלא בשימוש.
לפעמים אנחנו כוללים באפליקציות שלנו קוד שלא ממש נחוץ. המצב הזה קורה במיוחד אם אתם עובדים על האפליקציה במשך תקופה ארוכה, אם הצוות או יחסי התלות שלכם משתנים, ולפעמים אם ספרייה יתומה נשארת מאחור. זה בדיוק מה שקרה לנו.
בהתחלה השתמשנו בספריית Material Components כדי ליצור אב טיפוס לאפליקציה במהירות. עם הזמן עברנו למראה ולחוויה מותאמים אישית יותר, ושוכחנו לגמרי מהספרייה הזו. למזלנו, הבדיקה של כיסוי הקוד עזרה לנו למצוא אותו מחדש בחבילה שלנו.
תוכלו לבדוק את הנתונים הסטטיסטיים של כיסוי הקוד בכלי הפיתוח, גם את זמן הריצה וגם את זמן הטעינה של האפליקציה. אפשר לראות את שתי הפסים האדומים הגדולים בצילום המסך התחתון – יותר מ-95% מקוד ה-CSS שלנו לא היה בשימוש, וגם כמות גדולה של JavaScript.
הבעיה הזו זוהתה גם על ידי Lighthouse בבדיקת כללי ה-CSS שאינם בשימוש. הבדיקה הראתה חיסכון פוטנציאלי של יותר מ-400KB. אז חזרנו לקוד שלנו והסרנו את החלק של JavaScript וגם את החלק של CSS בספרייה הזו.
בעקבות זאת, הגודל של חבילת ה-CSS שלנו ירד פי 20, וזה די טוב עבור התחייבות קטנה באורך שורה אחת.
כמובן, ציון הביצועים שלנו עלה, וגם זמן הטעינה עד לאפשרות האינטראקציה השתפר משמעותית.
עם זאת, במקרה של שינויים כאלה, לא מספיק לבדוק רק את המדדים והציונים. הסרת קוד בפועל היא תמיד פעולה מסוכנת, לכן תמיד צריך לבדוק אם יש נסיגה פוטנציאלית.
הקוד שלנו לא היה בשימוש ב-95% מהמקרים – עדיין יש את ה-5% האלה במקום כלשהו. נראה שאחד מהרכיבים שלנו עדיין השתמש בסגנונות מהספרייה הזו - החיצים הקטנים בפס ההזזה של הדודל. אבל מכיוון שהיא הייתה קטנה כל כך, הצלחנו פשוט לשלב את הסגנונות האלה חזרה בלחצנים באופן ידני.
לכן, אם מסירים קוד, חשוב לוודא שיש תהליך בדיקה מתאים כדי למנוע נסיגה חזרה לקוד הקודם מבחינה חזותית.
הימנעות מטען שימושי עצום ברשת
אנחנו יודעים שמשאבים גדולים יכולים להאט את טעינת דפי האינטרנט. הם עלולים לעלות כסף למשתמשים שלנו ולהשפיע משמעותית על תוכניות הגלישה שלהם, אז חשוב מאוד לשים לב לזה.
מערכת Lighthouse הצליחה לזהות בעיה בחלק מהמטענים הייעודיים (payload) ברשת שלנו באמצעות ביקורת Enormous network payload.
כאן ראינו שיש לנו קוד בנפח של יותר מ-3MB שנשלח להורדה – וזה הרבה מאוד, במיוחד בנייד.
בראש הרשימה הזו, Lighthouse הדגיש שיש לנו חבילת ספקי JavaScript בנפח 2MB של קוד לא דחוס. זו גם בעיה ש-webpack מדגיש.
כמו שאומרים: הבקשה המהירה ביותר היא זו שלא נשלחת.
באופן אידיאלי כדאי למדוד את הערך של כל נכס שאתם מציגים למשתמשים, ולמדוד את הביצועים של הנכסים האלה ולבדוק אם כדאי באמת לשלוח את הנכסים הרצויים כבר בהתחלה. כי לפעמים אפשר לדחות את הנכסים האלה, לטעון אותם באופן מדורג או לעבד אותם במהלך זמן חוסר פעילות.
במקרה שלנו, מכיוון שאנחנו עובדים עם הרבה חבילות JavaScript, היינו ברי מזל כי לקהילת JavaScript יש קבוצה עשירה של כלים לבדיקת חבילות JavaScript.
התחלנו עם כלי הניתוח של חבילות Webpack, שדיווח לנו שאנחנו כוללים תלות בשם unicode, שהיא 1.6MB של JavaScript לאחר ניתוח, כך הרבה יותר.
לאחר מכן עברנו לעורך שלנו, והשתמשנו בתוסף של עלות הייבוא ל-Visual Code כדי להציג גרפית את העלות של כל מודול שייבאנו. כך גילינו איזה רכיב כלל קוד שמפנה למודול הזה.
לאחר מכן עברנו לכלי אחר, BundlePhobia. זהו כלי שמאפשר להזין את השם של כל חבילה ב-NPM ולראות בפועל מהו הגודל המשוער שלה אחרי דחיסה מינימלית ודחיסה ב-Gzip. מצאנו חלופה נהדרת למודול ה-slug שבו השתמשנו, שמשקלו רק 2.2KB, ולכן החלפנו אותו.
לכך הייתה השפעה רבה על הביצועים שלנו. בין השינוי הזה לבין גילוי הזדמנויות אחרות לצמצום גודל חבילת ה-JavaScript, חסכנו 2.1MB של קוד.
בסך הכול, ראינו שיפור של 65%, אם מביאים בחשבון את הגודל של החבילות האלה אחרי דחיסת gzip וצמצום. וגילינו שזה באמת כדאי לעשות בתהליך.
לכן, באופן כללי, כדאי להימנע משימוש בהורדות מיותרות באתרים ובאפליקציות. חשוב ליצור מלאי של הנכסים ולמדוד את ההשפעה שלהם על הביצועים. כך תוכלו להבין מהם הנכסים שהכי משפיעים על הביצועים שלכם, ולבדוק אותם באופן קבוע.
קיצור זמן האתחול של JavaScript באמצעות פיצול קוד
למרות שלמשא המועמס (payload) גדול ברשת יכולה להיות השפעה גדולה על האפליקציה שלנו, יש עוד דבר שיכול להשפיע מאוד, וזה JavaScript.
JavaScript הוא הנכס היקר ביותר. בנייד, אם שולחים חבילות גדולות של JavaScript, יכול להיות שהמשתמשים יצטרכו להמתין זמן רב יותר עד שיוכלו לקיים אינטראקציה עם רכיבי ממשק המשתמש. המשמעות היא שהם יכולים להקיש על ממשק המשתמש בלי שיקרה משהו משמעותי. לכן חשוב לנו להבין למה JavaScript עולה כל כך הרבה.
כך דפדפן מעבד JavaScript.
קודם כול אנחנו צריכים להוריד את הסקריפט. יש לנו מנוע JavaScript שצריך לנתח את הקוד הזה, להדר אותו ולהריץ אותו.
השלבים האלה לא נמשכים הרבה זמן במכשיר מתקדם כמו מחשב שולחני או מחשב נייד, ואולי אפילו בטלפון מתקדם. אבל בטלפון נייד ממוצע, התהליך הזה יכול להימשך פי 5 עד פי 10 יותר זמן. זה מה שמאט את האינטראקטיביות, ולכן חשוב לנו לנסות לצמצם את הזמן הזה.
כדי לעזור לכם לזהות את הבעיות האלה באפליקציה, הוספנו ל-Lighthouse בדיקה חדשה של זמן האתחול של JavaScript.
במקרה של אפליקציית Oodle, ראינו שהזמן שחלף בהפעלה של JavaScript היה 1.8 שניות. מה שקרה היה שייבאנו באופן סטטי את כל המסלולים והרכיבים שלנו לחבילת JavaScript מונוליתית אחת.
אחת מהשיטות לפתרון הבעיה הזו היא שימוש בפיצול קוד.
בשיטה של פיצול קוד, במקום לתת למשתמשים את מלוא הערך של ה-JavaScript של פיצה, מה יקרה אם תשלחו להם רק פרוסה אחת בכל פעם, לפי הצורך?
אפשר להחיל את פיצול הקוד ברמת המסלול או ברמת הרכיב. הוא עובד מצוין עם React ו-React Loadable, Vue.js, Angular, Polymer, Preact וספריות רבות אחרות.
שילבנו קוד לפיצול באפליקציה שלנו, ועברנו מייבוא סטטי לייבוא דינמי, וכך יכולנו לבצע טעינה מדורגת של קוד באופן אסינכרוני לפי הצורך.
ההשפעה של הפעולה הזו הייתה צמצום גודל החבילות, וגם קיצור זמן האתחול של JavaScript. זמן הטעינה ירד ל-0.78 שניות, והאפליקציה הפכה להיות מהירה יותר ב-56%.
באופן כללי, אם אתם מפתחים חוויית שימוש חזקה ב-JavaScript, הקפידו לשלוח את הקוד רק למשתמשים הרלוונטיים.
אם אתם משתמשים ב-webpack, כדאי להיעזר במושגים כמו חלוקת קוד, לבדוק רעיונות כמו tree shaking ולעיין במאגר webpack-libs-optimizations כדי לקבל כמה רעיונות לקיצור גודל הספרייה.
בצע אופטימיזציה לתמונות
באפליקציית Oodle אנחנו משתמשים בהרבה תמונות. לצערנו, ב-Lighthouse לא התלהבו ממנו כמונו. למעשה, נכשלנו בכל שלושת הבדיקות שקשורות לתמונות.
שכחנו לבצע אופטימיזציה של התמונות, לא הגדלנו אותן בצורה נכונה וגם הצלחנו להפיק תועלת מהשימוש בפורמטים אחרים של תמונות.
התחלנו באיתור דרכים לשיפור הביצועים של התמונות שלנו.
לביצוע אופטימיזציה חד פעמית, אפשר להשתמש בכלים חזותיים כמו ImageOptim או XNConvert.
גישה אוטומטית יותר היא להוסיף שלב של אופטימיזציה של תמונות לתהליך ה-build, באמצעות ספריות כמו imagemin.
כך תוכלו לוודא שהתמונות שיתווספו בעתיד יותאמו אוטומטית. שירותי CDN מסוימים, כמו Akamai או פתרונות של צד שלישי כמו Cloudinary, Fastly או Uploadcare, מציעים פתרונות מקיפים לאופטימיזציה של תמונות. כך תוכלו גם לארח את התמונות שלכם בשירותים האלה.
אם אתם לא רוצים לעשות זאת בגלל העלות או בעיות זמן אחזור, יש פרויקטים כמו Thumbor או Imageflow שמציעים חלופות לאירוח עצמי.
קובץ ה-PNG של הרקע סומן ב-webpack כגדול, ובצדק. אחרי שינוי הגודל שלו בהתאם למסך הצפייה והרצה שלו דרך ImageOptim, הצלחנו להקטין אותו ל-100KB, וזה גודל מקובל.
חזרה על הפעולה הזו בכמה תמונות באתר אפשרה לנו להפחית באופן משמעותי את משקל הדף הכולל.
שימוש בפורמט הנכון לתוכן מונפש
קובצי GIF יכולים להיות יקרים מאוד. באופן מפתיע, פורמט ה-GIF לא נועד מלכתחילה לפלטפורמת אנימציה. לכן, המעבר לפורמט וידאו מתאים יותר חוסך לכם חיסכון גדול מבחינת גודל הקובץ.
באפליקציית Oodle, השתמשנו ב-GIF כסצנת פתיחה בדף הבית. לפי Lighthouse, אפשר לחסוך יותר מ-7MB על ידי מעבר לפורמט וידאו יעיל יותר. הקליפ שלנו משקלל כ-7.3MB, יותר מדי בשביל כל אתר סביר, ולכן הפכנו אותו לאלמנט וידאו עם שני קובצי מקור – mp4 ו-WebM כדי לספק תמיכה רחבה יותר בדפדפנים.
השתמשנו בכלי 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 תציין את ההתנהגות הזו בבדיקת התמונות מחוץ למסך, ואפשר לראות אותה גם בחלונית הרשת של DevTools. אם אתם רואים הרבה תמונות נכנסות אבל רק כמה מהן גלויות בדף, כדאי לשקול להשתמש בטעינה איטית (lazy loading) במקום זאת.
הדפדפן עדיין לא תומך בטעינת פריטים בזמן אמת באופן מקורי, ולכן אנחנו צריכים להשתמש ב-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"/>
Lazysizes הוא רכיב חכם כי הוא לא רק עוקב אחרי השינויים בחשיפה של הרכיב, אלא גם מבצע שליפה מראש (prefetch) באופן יזום של רכיבים שנמצאים בסמוך לתצוגה כדי לספק חוויית משתמש אופטימלית.
הוא גם כולל שילוב אופציונלי של IntersectionObserver
, שמאפשר חיפושי הרשאות גישה יעילים מאוד.
אחרי השינוי הזה, אחזור התמונות שלנו מתבצע על פי דרישה. אם אתם רוצים להעמיק בנושא, כדאי לעיין בimages.guide – מקור מידע שימושי ומקיף מאוד.
איך לעזור לדפדפן לספק משאבים קריטיים מוקדם
לא לכל בייט שנשלח דרך הכבל לדפדפן יש את אותה מידת חשיבות, והדפדפן יודע זאת. לרוב הדפדפנים יש שיטות ניתוח נתונים (heuristics) כדי להחליט מה הם צריכים לאחזר קודם. לכן, לפעמים הם מאחזרים קובצי CSS לפני תמונות או סקריפטים.
אפשרות שימושית היא שאנחנו, ככותבים של הדף, נודיע לדפדפן מה באמת חשוב לנו. למרבה המזל, בשנים האחרונות ספקי הדפדפנים הוסיפו כמה תכונות שיעזרו לנו בכך, למשל רמזים לגבי משאבים כמו link rel=preconnect
, preload
או prefetch
.
היכולות האלה, שנוספו לפלטפורמת האינטרנט, עוזרות לדפדפן לאחזר את התוכן הנכון בזמן הנכון, והן יכולות להיות קצת יעילות יותר מחלק מהגישות המותאמות אישית לטעינה שמבוססות על לוגיקה, שמבוצעות באמצעות סקריפט במקום זאת.
נראה איך Lighthouse מנחה אותנו להשתמש ביעילות בחלק מהתכונות האלה.
הדבר הראשון שאומרים לנו ב-Lighthouse הוא להימנע מריבוי נסיעות הלוך ושוב יקרות לכל מקור שהוא.
באפליקציית Oodle אנחנו משתמשים הרבה ב-Google Fonts. בכל פעם שמשחררים גיליון סגנונות של Google Font בדף, הוא מחבר עד שני תת-דומיינים. מה ש-Lighthouse אומר לנו הוא שאם נוכל לחמם את החיבור הזה, נוכל לחסוך עד 300 אלפיות השנייה בזמן החיבור הראשוני.
בעזרת הקישור rel preconnect, אנחנו יכולים להסוות ביעילות את זמן האחזור הזה.
במיוחד במוצרים כמו Google Fonts, שבהם קובצי ה-CSS של גווני הגופן מתארחים ב-googleapis.com ומשאבי הגופן מתארחים ב-Gstatic, ההשפעה יכולה להיות משמעותית מאוד. החלנו את האופטימיזציה הזו וקיצנו כמה מאות אלפיות שנייה.
ההצעה הבאה של Lighthouse היא לטעון מראש בקשות למפתחות.
<link rel=preload>
הוא כלי יעיל מאוד. הוא מודיע לדפדפן על צורך במשאב כחלק מהניווט הנוכחי, ומנסה לגרום לדפדפן לאחזר אותו בהקדם האפשרי.
כאן Lighthouse אומר לנו שאנחנו צריכים לטעון מראש את המשאבים העיקריים של גופנים באינטרנט, כי אנחנו טוענים שני גופנים באינטרנט.
טעינת גופן אינטרנט מראש נראית כך: מציינים את rel=preload
, מעבירים את as
עם סוג הגופן ואז מציינים את סוג הגופן שרוצים לטעון, למשל woff2.
ההשפעה על הדף שלכם עשויה להיות דרמטית.
בדרך כלל, בלי להשתמש ב-link rel preload, אם גופנים לדפדפן הם קריטיים לדף, הדפדפן צריך קודם לאחזר את ה-HTML, לנתח את ה-CSS, ואז, הרבה יותר מאוחר, הוא יתחיל לאחזר את הגופנים לדפדפן.
באמצעות ה-link rel preload, ברגע שהדפדפן ינתח את ה-HTML, הוא יוכל להתחיל לאחזר את גופני ה-Web האלה הרבה יותר מוקדם. במקרה של האפליקציה שלנו, הצלחנו לקצר שנייה אחת מהזמן שנדרש לנו כדי ליצור עיבוד (רנדור) של טקסט באמצעות גופנים לאינטרנט.
אם תנסו לטעון מראש גופנים באמצעות Google Fonts, תגלו שיש לכך צד פחות נוח.
כתובות ה-URL של Google Fonts שצייננו בגווני הגופן שלנו בגיליונות הסגנון שלנו מתעדכנות על ידי צוות הגופנים באופן קבוע למדי. תאריך התפוגה של כתובות ה-URL האלה יכול לפוג או שהן יכולות להתעדכן בתדירות קבועה. לכן, אם אתם רוצים לשלוט באופן מלא בחוויית טעינת הגופן, מומלץ לארח בעצמכם את גופני האינטרנט. זה יכול להיות שימושי מאוד, כי הפעולה הזאת מספקת גישה לדברים כמו טעינה מראש של קישור rel.
במקרה שלנו, הכלי Google Web Fonts Helper מאוד שימושי לעזור לנו במצב אופליין של חלק מגופני האינטרנט האלו ולהגדיר אותם באופן מקומי, לכן כדאי לבדוק את הכלי הזה.
בין אם אתם משתמשים בגופנים באינטרנט כחלק מהמשאבים הקריטיים, ובין אם מדובר ב-JavaScript, נסו לעזור לדפדפן לספק את המשאבים הקריטיים שלכם בהקדם האפשרי.
ניסיוני: רמזים לתעדוף
יש לנו משהו מיוחד לשתף איתך היום. בנוסף לתכונות כמו רמזים לגבי משאבים וטעינה מראש, עבדנו על תכונה ניסיונית חדשה לדפדפן שנקראת רמזים לגבי תעדוף.
זוהי תכונה חדשה שמאפשרת להעביר לרשת הדפדפן רמז לגבי מידת החשיבות של משאב. היא חושפת מאפיין חדש – importance (חשיבות) – עם הערכים low (נמוך), high (גבוה) או auto (אוטומטי).
כך אנחנו יכולים להפחית את העדיפות של משאבים פחות חשובים, כמו סגנונות, תמונות או קריאות API לא קריטיות, כדי לצמצם את התחרות על המשאבים. אנחנו יכולים גם להגדיל את העדיפות של דברים חשובים יותר, כמו תמונות ה-Hero שלנו.
במקרה של אפליקציית Oodle, הנתונים האלה הובילו אותנו למקום אחד שבו אפשר לבצע אופטימיזציה.
לפני שהוספנו טעינת נתונים בזמן אמת (lazy loading) לתמונות שלנו, הדפדפן היה מבצע את הפעולות הבאות: היה לנו קרוסלה של תמונות עם כל הדודלים שלנו, והדפדפן היה מאחזר את כל התמונות ממש בהתחלה של הקרוסלה עם עדיפות גבוהה בשלב מוקדם. לצערנו, התמונות שבאמצע הקרוסלה היו החשובות ביותר למשתמש. אז מה שעשינו הוא להגדיר חשיבות של תמונות הרקע האלה לרמה נמוכה מאוד, של התמונות שבחזית לגבוהה מאוד, וההשפעה שלהם על ה-3G האיטי ועל המהירות שבה הצלחנו לאחזר ולעבד את התמונות האלה. אז זאת חוויה חיובית.
אנחנו מקווים להוסיף את התכונה הזו ל-Canary בעוד כמה שבועות, אז כדאי לעקוב אחר כך.
יש לכם אסטרטגיית טעינה של גופן אינטרנט
הטיפוגרפיה היא הבסיס לעיצוב טוב, ואם משתמשים בגופני אינטרנט, מומלץ לא לחסום את העיבוד של הטקסט, וסביר להניח שלא תרצו להציג טקסט בלתי נראה.
אנחנו מדגישים את הטקסט הזה ב-Lighthouse עכשיו, עם הביקורת להימנע משימוש בטקסט בלתי נראה בזמן טעינה של גופנים באינטרנט.
אם אתם טוענים את גופני האינטרנט באמצעות בלוק של חזית גופן, אתם מאפשרים לדפדפן להחליט מה לעשות אם חלף זמן רב מאז שהתחיל אחזור גופן האינטרנט. דפדפנים מסוימים ימתינו עד שלוש שניות לפני שיחזרו לגופן המערכת, ובסופו של דבר יחליפו אותו בגופן אחרי שהוא יירד.
אנחנו מנסים להימנע מהטקסט הבלתי נראה הזה, ולכן במקרה הזה לא היינו יכולים לראות את הדודלס הקלאסיים של השבוע אם הטעינה של הגופן לא הייתה מסתיימת בזמן. למרבה המזל, בעזרת התכונה החדשה שנקראת 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');
}
התכונה 'תצוגת גופן' עוזרת לכם להחליט איך יתבצע העיבוד של גופנים באינטרנט או החלפתם, על סמך משך הזמן הנדרש להחלפה.
במקרה הזה אנחנו משתמשים בהחלפת תצוגת גופנים. החלפה מעניקה לגופן פרק זמן של בלוק של אפס שניות, ותקופת החלפה אינסופית. המשמעות היא שהדפדפן ידפיס את הטקסט באופן כמעט מיידי בגופן חלופי, אם טעינת הגופן נמשכת זמן מה. והוא יחליף אותו ברגע שסוג הגופן יהיה זמין.
במקרה של האפליקציה שלנו, היתרון הגדול של השיטה הזו היה שהיא אפשרה לנו להציג טקסט משמעותי כבר בשלב מוקדם מאוד, ולעבור לגופן האינטרנט ברגע שהוא היה מוכן.
באופן כללי, אם אתם משתמשים בגופנים באינטרנט, כמו אחוז גדול מהאתרים באינטרנט, כדאי להשתמש בשיטה טובה לטעינת גופנים באינטרנט.
יש הרבה תכונות של פלטפורמת אינטרנט שאפשר להשתמש בהן כדי לבצע אופטימיזציה של חוויית הטעינה לגופנים, אבל כדאי גם לעיין במאגר המתכונים של גופנים באינטרנט (Web Font recipess) של Zach Leatherman, כי הוא ממש נהדר.
הפחתת מספר הסקריפטים שחוסמים את העיבוד
יש חלקים אחרים באפליקציה שאנחנו יכולים לדחוף מוקדם יותר בשרשרת ההורדה כדי לספק לפחות חוויית משתמש בסיסית מוקדם יותר.
בסרגל ציר הזמן של Lighthouse אפשר לראות שבמהלך השניות הראשונות האלה, שבהן כל המשאבים נטענים, המשתמש לא יכול לראות תוכן.
הורדה ועיבוד של גיליונות סגנונות חיצוניים מונעים מאיתנו להתקדם בתהליך הרינדור.
אנחנו יכולים לנסות לשפר את נתיב העיבוד הקריטי שלנו ולהציג חלק מהסגנונות מוקדם יותר.
אם מחלצים את הסגנונות שאחראים לעיבוד הראשוני ומטמיעים אותם ב-HTML, הדפדפן יוכל לעבד אותם מיד בלי לחכות שגיליונות הסגנון החיצוניים יגיעו.
במקרה שלנו, השתמשנו במודול NPM שנקרא Critical כדי להטמיע את התוכן הקריטי ב-index.html במהלך שלב ה-build.
המודול הזה ביצע את רוב העבודה הקשה בשבילנו, אבל עדיין היה קצת קשה לגרום לזה לפעול בצורה חלקה במסלולים שונים.
אם לא תהיו זהירים או שמבנה האתר שלכם מורכב מאוד, יכול להיות שיהיה קשה מאוד להטמיע את התבנית הזו אם לא תתכננו ארכיטקטורה של פגז אפליקציה כבר מההתחלה.
לכן חשוב מאוד להביא בחשבון שיקולים של ביצועים בשלב מוקדם. אם לא תתכננו את האתר כך שיהיה יעיל כבר מההתחלה, סביר להניח שתתקלו בבעיות בהמשך.
בסופו של דבר, הסיכון שלנו השתלם, הצלחנו להוציא לפועל את התוכן והאפליקציה התחילה לספק תוכן הרבה יותר מוקדם, ובעקבות זאת, זמן הפרסום המשמעותי הראשון שלנו השתפר משמעותית.
התוצאה
זו הייתה רשימה ארוכה של אופטימיזציות לשיפור ביצועים שיישמנו באתר שלנו. בואו נבחן את התוצאה. כך האפליקציה שלנו נטענת במכשיר נייד בינוני ברשת 3G, לפני ואחרי האופטימיזציה.
ציון הביצועים של Lighthouse עלה מ-23 ל-91. זו התקדמות יפה מבחינת המהירות. ביצענו בדיקה רציפה של כל השינויים בעקבות הדוח של Lighthouse. אם אתם רוצים לבדוק איך הטמענו טכנית את כל השיפורים, אתם מוזמנים להיכנס למאגר שלנו, במיוחד לבקשות העריכה (PR) שפורסמו בו.
ביצועים חזויים – חוויית משתמש מבוססת-נתונים
אנחנו מאמינים שלמידת מכונה מייצגת הזדמנות מלהיבה לעתיד בתחומים רבים. אחת מהרעיונות שאנחנו מקווים שיעודדו ניסויים נוספים בעתיד היא שנתונים אמיתיים יכולים להנחות את חוויית המשתמש שאנחנו יוצרים.
כיום אנחנו מקבלים החלטות שרירותיות רבות לגבי מה שהמשתמשים רוצים או צריכים, ולכן מה כדאי לשלוף מראש, לטעון מראש או לשמור מראש במטמון. אם נראה לנו נכון, אנחנו יכולים לתת עדיפות לכמות קטנה של משאבים, אבל קשה מאוד להתאים אותם לאתר כולו.
למעשה יש לנו נתונים זמינים שבאמצעותם אפשר לייעל את האופטימיזציה שלנו היום. באמצעות Google Analytics Reporting API אנחנו יכולים לבדוק את הדף הבא ברשימה של הדפים המובילים ואת אחוזי היציאה מכל כתובת URL באתר שלנו, וכך להסיק אילו משאבים כדאי לתת להם עדיפות.
אם אנחנו משלבים את הגישה הזו עם מודל הסתברות טוב, אנחנו נמנעים מבזבוז נתוני המשתמשים שלנו על ידי שליפה אגרסיבית מראש של תוכן. אנחנו יכולים להשתמש בנתונים האלה מ-Google Analytics, וליישם מודלים של למידת מכונה כמו שרשרות מרקוב או רשתות עצביות.
כדי להקל על הניסויים האלה, אנחנו שמחים להכריז על יוזמה חדשה שנקראת Guess.js.
Guess.js הוא פרויקט שמתמקד בחוויות משתמש מבוססות-נתונים באינטרנט. אנחנו מקווים שהדוח הזה יניע אתכם לבדוק את האפשרות להשתמש בנתונים כדי לשפר את ביצועי האתר, וגם מעבר לכך. כל הקוד הוא קוד פתוח וזמין ב-GitHub. הכלי הזה נוצר בשיתוף פעולה עם קהילת הקוד הפתוח על ידי Minko Gechev, Kyle Matthews מ-Gatsby, Katie Hempenius ועוד כמה אנשים.
אנחנו מזמינים אותך לנסות את Guess.js. נשמח לשמוע מה דעתך.
סיכום
ציונים ומדדים עוזרים לשפר את מהירות האינטרנט, אבל הם רק האמצעים, ולא היעדים עצמם.
כולנו חווינו טעינה איטית של דפים בזמן תנועה, אבל עכשיו יש לנו הזדמנות לספק למשתמשים שלנו חוויות שימוש מהנות יותר שנטענות מהר מאוד.
שיפור הביצועים הוא תהליך. הרבה שינויים קטנים יכולים להוביל לשיפורים גדולים. שימוש בכלי האופטימיזציה המתאימים ועיון בדוחות של Lighthouse יעזרו לכם לספק למשתמשים חוויה טובה יותר ומכילה יותר.
תודה מיוחדת ל-Ward Peeters, Minko Gechev, Kyle Mathews, Katie Hempenius, Dom Farolino, Yoav Weiss, Susie Lu, Yusuke Utsunomiya, Tom Ankers, Lighthouse ו-Google Doodles.