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

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

דחיסת נתונים – מדריך למתחילים

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

כדי להשיג את הביצועים הכי טובים, צריך לשלב את כל הטכניקות הבאות:

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

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

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

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

# 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
  1. ההודעות יכולות להכיל הערות שרירותיות – לפעמים הן נקראות תגובות – שמסומנות באמצעות הקידומת '#'. ההערות לא משפיעות על המשמעות של ההודעה או על ההתנהגויות שלה.
  2. ההודעות עשויות להכיל כותרות, שהן צמדי מפתח/ערך (מופרדים באמצעות ":" בדוגמה הקודמת) שמופיעים בתחילת ההודעה.
  3. הודעות מכילות מטען ייעודי (payload) של טקסט.

מה אפשר לעשות כדי להקטין את הגודל של ההודעה הקודמת, שמתחילה ב-200 תווים?

  1. התגובה מעניינת, אבל היא לא משפיעה על המשמעות של ההודעה. לסלק אותו כשמעבירים את ההודעה.
  2. יש טכניקות טובות לקידוד כותרות בצורה יעילה. לדוגמה, אם אתם יודעים שכל ההודעות כוללות את הערכים format ו-date, אתם יכולים להמיר אותם למזהים קצרים של מספרים שלמים ולשלוח רק אותם. עם זאת, יכול להיות שזה לא נכון, ולכן עדיף לא לגעת בזה כרגע.
  3. המטען הייעודי (payload) הוא טקסט בלבד. אנחנו לא יודעים מה התוכן של ההודעה (כנראה שהיא נוצרה באמצעות "secret-cipher"), אבל רק מהטקסט אפשר לראות שיש בה הרבה חזרות. אולי במקום לשלוח אותיות חוזרות, אפשר פשוט לספור את מספר האותיות החוזרות ולקודד אותן בצורה יעילה יותר. לדוגמה, "AAA" הופך ל-"3A", שמייצג רצף של שלוש אותיות A.

השילוב של הטכניקות האלה מניב את התוצאה הבאה:

format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A

ההודעה החדשה היא באורך 56 תווים, כלומר דחסתם את ההודעה המקורית ב-72%. זו ירידה משמעותית!

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

צמצום: עיבוד מקדים ואופטימיזציות ספציפיות להקשר

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

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

הדרך הכי טובה לדחוס נתונים מיותרים או כפולים היא למחוק אותם. עם זאת, אי אפשר פשוט למחוק נתונים שרירותיים. עם זאת, בהקשרים מסוימים שבהם יש לנו ידע ספציפי לגבי פורמט הנתונים והמאפיינים שלו, אפשר לצמצם באופן משמעותי את גודל המטען הייעודי (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 ובשלושת סוגי התוכן השונים שהוא מכיל:

  1. סימון HTML.
  2. CSS כדי להתאים אישית את ההצגה של דף.
  3. ‫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) מבוססי-טקסט לפני שהיא שולחת אותם למשתמש, ומבצעת דקומפרסיה שלהם כשהם מגיעים לדפדפן של המשתמש. התוצאה היא צמצום נוסף ומשמעותי של המשאבים האלה, ובעקבות זאת קיצור משך ההורדה.

  • ‫gzip ו-Brotli הם אלגוריתמים נפוצים לדחיסה שפועלים בצורה הכי טובה על נכסים מבוססי-טקסט: CSS,‏ JavaScript ו-HTML.
  • כל הדפדפנים המודרניים תומכים בדחיסת gzip ו-Brotli, ויפרסמו תמיכה בשתי הדחיסות בכותרת הבקשה של ה-HTTP‏ Accept-Encoding.
  • השרת צריך להיות מוגדר כך שיאפשר דחיסה. בדרך כלל, תוכנת שרת האינטרנט תאפשר למודולים לדחוס משאבים מבוססי-טקסט כברירת מחדל.
  • אפשר לכוונן את gzip ואת Brotli כדי לשפר את יחסי הדחיסה על ידי שינוי רמת הדחיסה. ב-gzip, הגדרות הדחיסה נעות בין 1 ל-9, כאשר 9 היא ההגדרה הכי טובה. ב-Brotli, הטווח הוא 0 עד 11, כאשר 11 הוא הערך הכי טוב. עם זאת, הגדרות דחיסה גבוהות יותר דורשות יותר זמן. לגבי משאבים שנדחסים באופן דינמי – כלומר, בזמן הבקשה – הגדרות באמצע הטווח נוטות להציע את האיזון הטוב ביותר בין יחס הדחיסה למהירות. עם זאת, אפשר להשתמש בדחיסה סטטית, שבה התגובה נדחסת מראש, ולכן אפשר להשתמש בהגדרות הדחיסה הכי אגרסיביות שזמינות לכל אלגוריתם דחיסה.
  • רשתות להעברת תוכן (CDN) מציעות בדרך כלל דחיסה אוטומטית של משאבים שעומדים בדרישות. רשתות CDN יכולות גם לנהל דחיסה דינמית וסטטית בשבילכם, כך שאתם לא צריכים לדאוג לעוד היבט של דחיסה.

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

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

כל הדפדפנים המודרניים מפרסמים תמיכה ב-gzip וב-Brotli בAccept-Encoding כותרת בקשת ה-HTTP. עם זאת, ספק האירוח אחראי לוודא ששרת האינטרנט מוגדר כראוי להצגת המשאב הדחוס כשהלקוח מבקש אותו.

קובץ אלגוריתם גודל לא דחוס גודל דחוס יחס דחיסה
angular-1.8.3.js Brotli ‫1,346 KiB ‫‎256 KiB 81%
angular-1.8.3.js gzip ‫1,346 KiB ‫329 KiB 76%
angular-1.8.3.min.js Brotli ‫173 KiB ‫53 KiB 69%
angular-1.8.3.min.js gzip ‫173 KiB ‫60 KiB 65%
jquery-3.7.1.js Brotli ‫302 KiB ‎69 KiB 77%
jquery-3.7.1.js gzip ‫302 KiB ‫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.

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

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

קריאה של כלי הפיתוח לגבי הגודל בפועל לעומת הגודל של ההעברה.
ייצוג של גודל ההעברה (כלומר, דחוס) של כל המשאבים בדף לעומת הגודל בפועל שלהם, כפי שמוצג בחלונית Network בכלי הפיתוח ל-Chrome.

בדומה לתמונה הקודמת, אמור להופיע פירוט של:

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

השפעות על Core Web Vitals

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

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

  • משאבי HTML שעברו מיניפיקציה ודחיסה יכולים לשפר את הטעינה של ה-HTML, את יכולת הגילוי של משאבי המשנה שלו, ולכן לשפר את הטעינה שלהם. השימוש בטכניקה הזו יכול לשפר את המהירות שבה נטען רכיב התוכן הכי גדול (LCP) בדף. אפשר להשתמש ברמזים למשאבים כמו rel="preload" כדי להשפיע על הגילוי של משאבים, אבל שימוש ביותר מדי רמזים עלול לגרום לבעיות ברוחב הפס. אם דוחסים את תגובת ה-HTML לבקשת ניווט, סורק הטעינה מראש יכול לגלות את המשאבים שבה בהקדם האפשרי.
  • אפשר גם לטעון חלק מהמועמדים ל-LCP מוקדם יותר באמצעות דחיסה. לדוגמה, אפשר לצמצם את משך טעינת המשאב של תמונות SVG שהן מועמדות ל-LCP באמצעות דחיסה מבוססת-טקסט. זה שונה מאופטימיזציות שאתם מבצעים בסוגים אחרים של תמונות – שנדחסות באופן מובנה באמצעות שיטות דחיסה אחרות – כמו דחיסה עם אובדן נתונים בתמונות JPEG.
  • בנוסף, צמתי טקסט יכולים להיות גם מועמדים ל-LCP. השיטות שמתוארות במדריך הזה תלויות בכך שאתם משתמשים בגופן אינטרנט לטקסט בדפי האינטרנט. אם משתמשים בגופן אינטרנט, צריך לפעול לפי השיטות המומלצות לאופטימיזציה של גופני אינטרנט. עם זאת, אם לא משתמשים בגופנים לאינטרנט – אלא בגופנים של המערכת שמוצגים בלי להשפיע על משך טעינת המשאבים – מזעור ודחיסה של קובצי ה-CSS יקצרו את משך הטעינה, מה שאומר שעיבוד של צמתי טקסט פוטנציאליים של LCP יכול להתבצע מוקדם יותר.

סיכום

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

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

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