בנוסף להסרת הורדות של משאבים מיותרים, הדרך הכי טובה לשפר את מהירות טעינת הדף היא להקטין את גודל ההורדה הכולל על ידי אופטימיזציה ודחיסת נתונים של המשאבים שנותרו.
דחיסת נתונים – מדריך למתחילים
אחרי שמגדירים את האתר כך שלא יוריד משאבים שלא בשימוש, השלב הבא הוא לדחוס את כל המשאבים הרלוונטיים שנותרו שהדפדפן צריך להוריד. בהתאם לסוג המשאב (טקסט, תמונות, גופנים וכו'), יש הרבה שיטות שונות שאפשר לבחור מתוכן: כלים כלליים שאפשר להפעיל בשרת האינטרנט, אופטימיזציות של עיבוד מקדים לסוגי תוכן ספציפיים ואופטימיזציות ספציפיות למשאבים שדורשות קלט מהמפתח.
כדי להשיג את הביצועים הטובים ביותר, צריך לשלב את כל השיטות הבאות:
- דחיסה היא תהליך של קידוד מידע באמצעות פחות ביטים.
- הסרת נתונים מיותרים תמיד מניבה את התוצאות הטובות ביותר.
- יש הרבה שיטות ואלגוריתמים שונים לדחיסה.
- כדי להשיג את הדחיסה הטובה ביותר, תצטרכו להשתמש במגוון טכניקות.
התהליך של הקטנת נפח הנתונים נקרא דחיסת נתונים. הרבה אנשים תרמו אלגוריתמים, טכניקות ואופטימיזציות כדי לשפר את יחסי הדחיסה, את מהירות הדחיסה ואת הזיכרון שנדרש לאלגוריתמים שונים של דחיסה.
דיון מלא בנושא דחיסת נתונים חורג בהרבה מהיקף המדריך הזה. עם זאת, חשוב להבין ברמה הכללית איך הדחיסה פועלת, ואת השיטות שבהן אפשר להשתמש כדי להקטין את הגודל של נכסים שונים שהדפים שלכם דורשים.
כדי להמחיש את העקרונות הבסיסיים של השיטות האלה, נבחן את תהליך האופטימיזציה של פורמט פשוט של הודעת טקסט שהומצא רק בשביל הדוגמה הזו:
# Below is a secret message, which consists of a set of headers in
# key-value format followed by a newline and the encrypted message.
format: secret-cipher
date: 08/25/16
AAAZZBBBBEEEMMM EEETTTAAA
- הודעות יכולות להכיל הערות שרירותיות – לפעמים הן נקראות תגובות – שמסומנות בקידומת "#". ההערות לא משפיעות על משמעות ההודעה או על ההתנהגות שלה.
- הודעות יכולות להכיל כותרות, שהן צמדי מפתח/ערך (מופרדים באמצעות
":"בדוגמה הקודמת) שמופיעים בתחילת ההודעה. - ההודעות מכילות מטען ייעודי (payload) של טקסט.
מה אפשר לעשות כדי להקטין את ההודעה הקודמת, שמתחילה ב-200 תווים?
- התגובה מעניינת, אבל היא לא משפיעה על משמעות ההודעה. צריך להסיר אותו כשמעבירים את ההודעה.
- יש שיטות טובות לקודד כותרות בצורה יעילה. לדוגמה, אם אתם יודעים שבכל ההודעות יש "פורמט" ו "תאריך", אתם יכולים להמיר אותם למזהים קצרים של מספרים שלמים ולשלוח רק אותם. אבל יכול להיות שזה לא נכון, אז עדיף לא לגעת בזה כרגע.
- המטען הייעודי (payload) הוא טקסט בלבד. אנחנו לא יודעים מה התוכן האמיתי של הקובץ (כנראה שהוא משתמש ב-
"secret-cipher"), אבל רק מהסתכלות על הטקסט אפשר לראות שיש בו הרבה יתירות. אולי במקום לשלוח אותיות שחוזרות על עצמן, אפשר פשוט לספור את מספר האותיות שחוזרות על עצמן ולקודד אותן בצורה יעילה יותר. לדוגמה,"AAA"הופך ל-"3A", שמייצג רצף של שלוש אותיות A.
שילוב של השיטות האלה מניב את התוצאה הבאה:
format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A
ההודעה החדשה היא באורך 56 תווים, כלומר דחסתם את ההודעה המקורית ב-72%. זו הפחתה משמעותית.
זו דוגמה פשוטה שמראה איך אלגוריתמים של דחיסה יכולים להקטין ביעילות את גודל ההעברה של משאבים מבוססי-טקסט. בפועל, אלגוריתמים של דחיסה הם הרבה יותר מתוחכמים מהדוגמה הקודמת, ובאינטרנט אפשר להשתמש באלגוריתמים של דחיסה כדי לקצר באופן משמעותי את זמני ההורדה של משאבים. כשמפעילים דחיסה על נכסים מבוססי-טקסט, דף האינטרנט יכול להשקיע פחות זמן בטעינת משאבים, כך שהמשתמשים יכולים לראות את ההשפעות של המשאבים האלה מהר יותר מאשר בלי דחיסה.
הקטנה: עיבוד מראש ואופטימיזציות ספציפיות להקשר
השיטה הראשונה שנדון בה היא הקטנה. הקטנה היא לא אלגוריתם דחיסה, אלא דרך להסיר תווים מיותרים מקוד המקור כדי שבני אדם יוכלו לקרוא את המשאבים בקלות רבה יותר. עם זאת, הקריאוּת הזו לא נחוצה כדי לשמור על הפונקציונליות של קוד המקור הזה באתרים בסביבת הייצור, והיא יכולה לעכב את הטעינה של משאבים באינטרנט.
הקטנה היא סוג של אופטימיזציה ספציפית לתוכן שיכולה להקטין באופן משמעותי את גודל המשאבים שנשלחים, והכי טוב להחיל את האופטימיזציות כחלק מתהליך ה-build והפריסה. לדוגמה, כלי אריזה הם סוג נפוץ של תוכנה שיכולה להקטין משאבים באופן אוטומטי רגע לפני פריסת קוד ייצור חדש באתר.
הדרך הכי טובה לדחוס נתונים מיותרים היא פשוט למחוק אותם. עם זאת, אי אפשר למחוק נתונים באופן שרירותי. עם זאת, בהקשרים מסוימים שבהם יש לנו ידע ספציפי על התוכן של פורמט הנתונים והמאפיינים שלו, אפשר להקטין באופן משמעותי את גודל המטען הייעודי (payload) בלי להשפיע על המשמעות או היכולות שלו בפועל.
<html>
<head>
<style>
/* awesome-container is only used on the landing page */
.awesome-container {
font-size: 120%;
}
.awesome-container {
width: 50%;
}
</style>
</head>
<body>
<!-- awesome container content: START -->
<div>
This is my awesome container, and it is <em>so</em> awesome.
</div>
<!-- awesome container content: END -->
<script>
awesomeAnalytics(); // Beacon conversion metrics
</script>
</body>
</html>
נבחן את קטע הקוד הקודם ב-HTML ואת שלושת סוגי התוכן השונים שהוא מכיל:
- תגי עיצוב ב-HTML.
- CSS להתאמה אישית של תצוגת הדף.
- JavaScript כדי להפעיל אינטראקציות ויכולות מתקדמות אחרות בדף.
לכל אחד מסוגי התוכן האלה יש כללים שונים לגבי מה שנחשב לתוכן תקין, כללים שונים לציון הערות וכן הלאה. אבל השאלה שנותרה היא "איך אפשר להקטין את הדף הזה?"
- הערות בקוד הן החברות הכי טובות של המפתחים, אבל הדפדפן לא צריך אותן. הסרת הערות ב-CSS (
/* ... */), ב-HTML (<!-- ... -->) וב-JavaScript (// ...) מקטינה את הגודל הכולל של הדף ושל משאבי המשנה שלו. - דוחס CSS "חכם" יכול לזהות שאנחנו משתמשים בדרך לא יעילה להגדרת כללים ל-
.awesome-container, ולכווץ את שתי ההצהרות לאחת בלי להשפיע על סגנונות אחרים, וכך לחסוך עוד בייטים. במערך גדול של כללי CSS, הסרת יתירות מהסוג הזה יכולה להצטבר, אבל יכול להיות שלא ניתן להחיל אותה באופן אגרסיבי, כי לעיתים קרובות הסלקטורים משוכפלים בהכרח בהקשרים שונים, כמו בשאילתות מדיה. - רווחים וטאבים הם כלים נוחים למפתחים ב-HTML, ב-CSS וב-JavaScript. דוחס נוסף יכול להסיר את כל הכרטיסיות והרווחים. בניגוד לטכניקות אחרות של ביטול כפילויות, אפשר להשתמש באופטימיזציה מהסוג הזה באופן די אגרסיבי, כל עוד הרווחים או הטאבים האלה לא נחוצים להצגת הדף. לדוגמה, כדאי לשמור על הרווחים בתוך קטעי טקסט במסמך HTML, כי הם מבטיחים שהתוכן שהמשתמשים יראו בפועל יהיה קריא.
<html><head><style>.awesome-container{font-size:120%;width:50%}</style></head><body><div>This is my awesome container, and it is <em>so</em> awesome.</div><script>awesomeAnalytics()</script></body></html>
אחרי שמבצעים את השלבים הקודמים, מספר התווים בדף יורד מ-516 ל-204, כלומר חיסכון של כ-60%. נכון, הוא לא ממש קריא, אבל הוא לא צריך להיות קריא כדי שיהיה אפשר להשתמש בו. שיטות פיתוח מודרניות גם מאפשרות לכם להפריד בין הגרסאות הקריאות והמעוצבות של קוד המקור לבין הקוד שעבר אופטימיזציה ונשלח לסביבת הייצור. בשילוב עם מפות מקור, שמספקות ייצוג קריא של קוד הייצור שעבר שינוי, קל יותר לפתור באגים בסביבת הייצור. כך אפשר ליהנות מחוויית פיתוח טובה וגם לבצע אופטימיזציה של הביצועים כדי לשפר את חוויית המשתמש.
הדוגמה הקודמת ממחישה נקודה חשובה: דוחס למטרות כלליות – למשל, כזה שנועד לדחוס טקסט שרירותי – יכול לעשות עבודה די טובה בדחיסת הדף בדוגמה הקודמת, אבל הוא אף פעם לא יידע להסיר את ההערות, לכווץ כללי CSS או לבצע עשרות אופטימיזציות אחרות שספציפיות לתוכן. לכן חשוב לבצע עיבוד מקדים, כיווץ ואופטימיזציות אחרות שמותאמות להקשר.
באופן דומה, אפשר להרחיב את השיטות שמתוארות למעלה מעבר לנכסים שמבוססים על טקסט בלבד. תמונות, סרטונים וסוגי תוכן אחרים מכילים מטא-נתונים ומטענים ייעודיים (payloads) משלהם. לדוגמה, כשמצלמים תמונה במצלמה, הקובץ שלה בדרך כלל כולל הרבה מידע נוסף: הגדרות המצלמה, מיקום וכו'. בהתאם לאפליקציה, הנתונים האלה יכולים להיות קריטיים (לדוגמה, אתר לשיתוף תמונות) או חסרי תועלת לחלוטין. כדאי לשקול אם להסיר אותו. בפועל, המטא-נתונים האלה יכולים להוסיף עד עשרות קילובייטים לכל תמונה.
בקיצור, כשלב ראשון באופטימיזציה של יעילות הנכסים, כדאי ליצור מלאי של סוגי התוכן השונים ולחשוב אילו סוגים של אופטימיזציות ספציפיות לתוכן אפשר להחיל כדי להקטין את הגודל שלהם. אחרי שתבינו מהן, תוכלו להפוך את האופטימיזציות האלה לאוטומטיות על ידי הוספה שלהן לשלבי ה-build וההפצה, כדי לוודא שהאופטימיזציות מיושמות באופן עקבי בכל גרסה חדשה שמופצת לסביבת הייצור.
דחיסת טקסט באמצעות אלגוריתמים לדחיסת נתונים
השלב הבא בהקטנת הגודל של נכסים מבוססי-טקסט הוא להחיל עליהם אלגוריתם דחיסה. הוא מחפש באופן אגרסיבי דפוסים שחוזרים על עצמם במטענים מבוססי-טקסט לפני שהוא שולח אותם למשתמש, ומבטל את הדחיסה שלהם כשהם מגיעים לדפדפן של המשתמש. התוצאה היא צמצום נוסף ומשמעותי של המשאבים האלה, וזמני הורדה מהירים יותר.
- gzip ו-Brotli הם אלגוריתמים נפוצים לדחיסה, שפועלים בצורה הכי טובה על נכסים מבוססי-טקסט: CSS, JavaScript ו-HTML.
- כל הדפדפנים המודרניים תומכים בדחיסת gzip ו-Brotli, ומפרסמים תמיכה בשניהם בכותרת הבקשה
Accept-EncodingHTTP. - צריך להגדיר את השרת כך שיאפשר דחיסה. בדרך כלל, תוכנת שרת האינטרנט תפעיל מודולים לדחיסת משאבים מבוססי-טקסט כברירת מחדל.
- אפשר לשנות את רמת הדחיסה של gzip ו-Brotli כדי לשפר את יחסי הדחיסה. ב-gzip, הגדרות הדחיסה נעות בין 1 ל-9, כאשר 9 היא הטובה ביותר. ב-Brotli, הטווח הוא בין 0 ל-11, כאשר 11 הוא הערך הטוב ביותר. עם זאת, הגדרות דחיסה גבוהות יותר דורשות יותר זמן. במשאבים שנדחסים באופן דינמי (כלומר בזמן הבקשה), הגדרות באמצע הטווח בדרך כלל מציעות את הפשרה הטובה ביותר בין יחס הדחיסה למהירות. עם זאת, אפשר להשתמש בדחיסה סטטית, שבה התגובה נדחסת מראש, ולכן אפשר להשתמש בהגדרות הדחיסה האגרסיביות ביותר שזמינות לכל אלגוריתם דחיסה.
- רשתות להעברת תוכן (CDN) בדרך כלל מציעות דחיסה אוטומטית של משאבים שעומדים בדרישות. רשתות CDN יכולות גם לנהל בשבילכם דחיסה דינמית וסטטית, כך שאתם לא צריכים לדאוג לגבי היבט הדחיסה.
gzip ו-Brotli הם דוחסים נפוצים שאפשר להחיל על כל זרם של בייטים. מאחורי הקלעים, הם זוכרים חלק מהתוכן של קובץ שנבדק בעבר, ואז מנסים למצוא ולהחליף קטעי נתונים כפולים בצורה יעילה.
בפועל, גם gzip וגם Brotli פועלים בצורה הטובה ביותר על תוכן שמבוסס על טקסט, ולעיתים קרובות מגיעים לשיעורי דחיסה של עד 70-90% בקבצים גדולים יותר. עם זאת, הפעלת האלגוריתמים האלה על נכסים שכבר דחוסים באמצעות אלגוריתמים חלופיים – כמו רוב הפורמטים של תמונות שמשתמשים בטכניקות דחיסה ללא אובדן מידע או עם אובדן מידע – מניבה שיפור מועט, אם בכלל.
כל הדפדפנים המודרניים מפרסמים תמיכה ב-gzip וב-Brotli ב-request header של בקשת HTTP Accept-Encoding. עם זאת, ספק האירוח אחראי לוודא ששרת האינטרנט מוגדר כראוי כדי להציג את המשאב הדחוס כשהלקוח מבקש אותו.
| קובץ | אלגוריתם | גודל לא דחוס | גודל דחוס | יחס דחיסה |
|---|---|---|---|---|
| angular-1.8.3.js | Brotli | 1,346KiB | 256 KiB | 81% |
| angular-1.8.3.js | gzip | 1,346KiB | 329 KiB | 76% |
| angular-1.8.3.min.js | Brotli | 173 KiB | 53KiB | 69% |
| angular-1.8.3.min.js | gzip | 173 KiB | 60 KiB | 65% |
| jquery-3.7.1.js | Brotli | 302KiB | 69 KiB | 77% |
| jquery-3.7.1.js | gzip | 302KiB | 83 KiB | 73% |
| jquery-3.7.1.min.js | Brotli | 85 KiB | 27 KiB | 68% |
| jquery-3.7.1.min.js | gzip | 85 KiB | 30 KiB | 65% |
| lodash-4.17.21.js | Brotli | 531 KiB | 73 KiB | 86% |
| lodash-4.17.21.js | gzip | 531 KiB | 94 KiB | 82% |
| lodash-4.17.21.min.js | Brotli | 71 KiB | 23 KiB | 68% |
| lodash-4.17.21.min.js | gzip | 71 KiB | 25 KiB | 65% |
בטבלה שלמעלה מוצג החיסכון שדחיסה ב-Brotli וב-gzip יכולה לספק לכמה ספריות JavaScript מוכרות. החיסכון נע בין 65% ל-86%, בהתאם לקובץ ולאלגוריתם. לשם השוואה, רמת הדחיסה המקסימלית הופעלה על כל קובץ גם ב-Brotli וגם ב-gzip. בכל מקום שאפשר, עדיף להשתמש ב-Brotli במקום ב-gzip.
הפעלת דחיסה היא אחת מהאופטימיזציות הפשוטות והיעילות ביותר ליישום. אם האתר שלכם לא מנצל את היתרונות של HTTP/2, אתם מפספסים הזדמנות גדולה לשפר את הביצועים בשביל המשתמשים. למרבה המזל, שרתי אינטרנט רבים מספקים הגדרות ברירת מחדל שמאפשרות את האופטימיזציה החשובה הזו, ורשתות CDN בפרט יעילות מאוד בהטמעה שלה באופן שמאזן בין מהירות הדחיסה ליחס הדחיסה.
דרך מהירה לראות את הדחיסה בפעולה היא לפתוח את כלי הפיתוח ל-Chrome, לפתוח את החלונית Network, לטעון דף לבחירתכם ולראות את החלק התחתון של החלונית Network.
כמו בתמונה הקודמת, אמור להופיע פירוט של:
- מספר הבקשות, שהוא מספר המשאבים שנטענו בדף.
- גודל ההעברה של כל הבקשות. המדד הזה משקף את יעילות הדחיסה של כל אחד מהמשאבים בדף.
- גודל המשאב של כל הבקשות. הנתון הזה משקף את גודל המשאבים של הדף אחרי שהם נפרסו.
ההשפעות על Core Web Vitals
כדי למדוד את השיפורים בביצועים, צריך מדדים שמשקפים את השיפורים האלה. היוזמה של Core Web Vitals נועדה ליצור מדדים שמשקפים את חוויית המשתמש בפועל ולהגביר את המודעות אליהם. זאת בניגוד למדדים, כמו זמן טעינה של דף, שלא משקפים באופן ברור את איכות חוויית המשתמש.
כשמיישמים את האופטימיזציות שמתוארות במדריך הזה על המשאבים באתר, ההשפעות על מדדי ה-Core Web Vitals יכולות להשתנות בהתאם למשאבים שעברו אופטימיזציה ולמדדים הרלוונטיים. עם זאת, הנה כמה מקרים שבהם יישום האופטימיזציות האלה יכול לשפר את מדדי ה-Core Web Vitals של האתר:
- משאבי HTML שעוברים כיווץ ודחיסה יכולים לשפר את הטעינה של ה-HTML הזה, את יכולת הגילוי של משאבי המשנה שלו, וכתוצאה מכך לשפר את הטעינה שלהם. זה יכול לשפר את המדד המהירות שבה נטען רכיב התוכן הכי גדול (LCP) של הדף. אפשר להשתמש ברמזים למשאבים כמו
rel="preload"כדי להשפיע על היכולת לגלות משאבים, אבל שימוש ביותר מדי רמזים עלול לגרום לבעיות של תחרות על רוחב הפס. אם תדאגו לכך שתגובת ה-HTML לבקשת ניווט תהיה דחוסה, סורק הטעינה מראש יוכל לגלות את המשאבים שבה בהקדם האפשרי. - אפשר גם לטעון מהר יותר חלק מהמועמדים ל-LCP באמצעות דחיסה. לדוגמה, אפשר להקטין את משך הטעינה של המשאבים בתמונות SVG שנחשבות למועמדות ל-LCP באמצעות דחיסה מבוססת-טקסט. האופטימיזציה הזו שונה מאופטימיזציה של סוגי תמונות אחרים, שנדחסים באופן מהותי בשיטות דחיסה אחרות, כמו תמונות JPEG שמשתמשות בדחיסת נתונים (lossy).
- בנוסף, צומתי טקסט יכולים גם להיות מועמדים ל-LCP. האופן שבו משתמשים בשיטות שמתוארות במדריך הזה תלוי בשאלה אם אתם משתמשים בגופן אינטרנט לטקסט בדפי האינטרנט שלכם. אם אתם משתמשים בגופן אינטרנט, כדאי לפעול לפי השיטות המומלצות לאופטימיזציה של גופני אינטרנט. עם זאת, אם אתם לא משתמשים בגופני אינטרנט, אלא בגופני מערכת שמוצגים בלי להאריך את משך הטעינה של המשאבים, הקטנה ודחיסה של קובצי ה-CSS יקצרו את משך הזמן הזה, וכך העיבוד של צומתי טקסט פוטנציאליים של LCP יכול להתרחש מוקדם יותר.
סיכום
האופן שבו מבצעים אופטימיזציה של הקידוד וההעברה של נכסים מבוססי-טקסט הוא קונספט בסיסי של ביצועים, אבל יש לו השפעה גדולה. חשוב לוודא שאתם עושים כל מה שאפשר כדי שמשאבים שאפשר להקטין ולדחוס ייהנו מהאופטימיזציות האלה.
חשוב עוד יותר לוודא שהתהליכים האלה מתבצעים באופן אוטומטי. כדי להקטין את הקבצים, משתמשים בכלי לאיחוד קבצים (bundler) ומחילים את ההקטנה על המשאבים המתאימים. חשוב לוודא שהגדרת שרת האינטרנט תומכת בדחיסה, אבל מעבר לכך, כדאי להשתמש בדחיסה היעילה ביותר שזמינה. כדי להפוך את זה לפשוט ככל האפשר, השתמשו ברשתות CDN כדי להפוך את הדחיסה לאוטומטית, כי הן לא רק יכולות לדחוס משאבים בשבילכם, אלא גם לעשות את זה מהר מאוד.
אם תטמיעו את המושגים הבסיסיים האלה של ביצועים בארכיטקטורה של האתר, תוכלו לוודא שמאמצי האופטימיזציה של הביצועים מתבססים על בסיס טוב, ושהאופטימיזציות הבאות יכולות להתבסס על בסיס יציב של שיטות בסיסיות טובות.