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

איליה גריגוריק
איליה גריגוריק

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

דחיסת נתונים 101

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

קובץ אלגוריתם גודל לא דחוס גודל דחוס יחס דחיסה
אנגלי-1.8.3.js ברוטלי KiB 1,346 KiB 256 81%
אנגלי-1.8.3.js gzip KiB 1,346 KiB 329 76%
אנגלי-1.8.3.min.js ברוטלי KiB 173 KiB 53 69%
אנגלי-1.8.3.min.js gzip KiB 173 KiB 60 65%
Jquery-3.7.1.js ברוטלי KiB 302 KiB 69 77%
Jquery-3.7.1.js gzip KiB 302 KiB 83 73%
Jquery-3.7.1.min.js ברוטלי KiB 85 KiB 27 68%
Jquery-3.7.1.min.js gzip KiB 85 KiB 30 65%
lodash-4.17.21.js ברוטלי KiB 531 KiB 73 86%
lodash-4.17.21.js gzip KiB 531 KiB 94 82%
lodash-4.17.21.min.js ברוטלי KiB 71 KiB 23 68%
lodash-4.17.21.min.js gzip KiB 71 KiB 25 65%

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

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

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

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

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

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

ההשפעות על מדדי הליבה לבדיקת חוויית המשתמש באתר

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

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

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

סיכום

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

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

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