שיטות מומלצות לגופנים

אופטימיזציה של גופני אינטרנט לבדיקת Core Web Vitals

Katie Hempenius
Katie Hempenius

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

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

טעינת גופן

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

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

צילום מסך של הכרטיסייה 'תזמון' בכלי הפיתוח

הסבר על @font-face

לפני שנדבר על השיטות המומלצות לטעינת גופנים, חשוב להבין איך פועל @font-face ואיך הוא משפיע על טעינת הגופנים.

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

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

יש טעות נפוצה לגבי הבקשה של גופן כשמתבצעת פגישה עם הצהרת @font-face – זה לא נכון. ההצהרה @font-face לא גורמת להורדת הגופן בפני עצמה. במקום זאת, מתבצעת הורדה של גופן רק אם יש אליו הפניה באמצעות עיצוב שנעשה בו שימוש בדף. לדוגמה, כך:

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

h1 {
  font-family: "Open Sans"
}

במילים אחרות, בדוגמה שלמעלה, Open Sans יירד רק אם הדף יכיל אלמנט <h1>.

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

הצהרות על גופנים בתוך שורה

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

<head>
  <style>
    @font-face {
        font-family: "Open Sans";
        src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    }

    body {
        font-family: "Open Sans";
    }

    ...etc.

  </style>
</head>

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

קישור מראש למקורות חיוניים של צד שלישי

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

<head>
  <link rel="preconnect" href="https://fonts.com">
</head>

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

<head>
  <link rel="preconnect" href="https://fonts.com">
  <link rel="preconnect" href="https://fonts.com" crossorigin>
</head>

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

<head>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>

חשוב להיזהר כשמשתמשים ב-preload כדי לטעון גופנים

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

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

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

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

העברת גופן

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

שימוש בגופנים באירוח עצמי

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

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

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

שימוש ב-WOFF2

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

בשל התמיכה בדפדפן, מומחים ממליצים כעת להשתמש ב-WOFF2 בלבד:

למעשה, אנחנו חושבים שהגיע הזמן להכריז: צריך להשתמש רק ב-WOFF2 ולשכוח מכל השאר.

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

בראם סטיין, מתוך 'אלמנך האינטרנט לשנת 2022'

קבוצות משנה של גופנים

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

התיאור unicode-range בהצהרה @font-face מודיע לדפדפן באילו תווים אפשר להשתמש בגופן.

@font-face {
    font-family: "Open Sans";
    src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    unicode-range: U+0025-00FF;
}

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

בדרך כלל משתמשים ב-unicode-range בשילוב עם שיטת יצירת קבוצות משנה. גופן משנה כולל חלק קטן יותר מהגליפים שנכללו בקובץ הגופן המקורי. לדוגמה, במקום להציג את כל התווים לכל המשתמשים, אתר יכול ליצור תת-גופנים נפרדים לתווים לטיניים ולתווים קיריליים. מספר הגליפים בכל גופן משתנה מאוד: גופנים לטינית מכילים בדרך כלל בין 100 ל-1,000 גליפים לכל גופן, ואילו גופנים של CJK יכולים להכיל יותר מ-10,000 תווים. הסרת גליפים שאינם בשימוש עשויה לצמצם משמעותית את גודל הקובץ של הגופן.

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

/* devanagari */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJbecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
}
/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJnecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJfecnFHGPc.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

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

אפשר גם ליצור קבוצות משנה של גופנים באופן ידני, אם ספק הגופנים מאפשר זאת, דרך ממשק API (Google Fonts תומך בכך על ידי מתן הפרמטר text) או על ידי עריכה ידנית של קובצי הגופנים ולאחר מכן אירוח עצמאי. כלים ליצירת קבוצות משנה של גופנים כוללים את subfont ואת glyphanger. עם זאת, חשוב לבדוק אם הרישיון של הגופנים שבהם אתם משתמשים מאפשר יצירת קבוצות משנה ואירוח עצמי.

שימוש בפחות גופנים לאינטרנט

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

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

כדי להשתמש בגופן המערכת ב-CSS, צריך לרשום את system-ui כמשפחת הגופנים:

font-family: system-ui

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

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

רינדור גופנים

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

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

אפשר להגדיר את ההתנהגות הזו באמצעות המאפיין font-display. לבחירה הזו יכולות להיות השלכות משמעותיות: ל-font-display יש פוטנציאל להשפיע על LCP,‏ FCP ויציבות הפריסה.

בחירת אסטרטגיה מתאימה ל-font-display

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

@font-face {
  font-family: Roboto, Sans-Serif
  src: url(/fonts/roboto.woff) format('woff'),
  font-display: swap;
}

יש חמישה ערכים אפשריים ל-font-display:

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

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

ברוב האתרים, אלה שלוש השיטות הכי רלוונטיות:

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

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

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

חשוב גם לזכור שאפשר לשלב בין שתי הגישות האלה: לדוגמה, אפשר להשתמש ב-font-display: swap למיתוג ולרכיבים אחרים בדף ששונים מבחינה ויזואלית, ולהשתמש ב-font-display: optional לגופנים שמשמשים בגוף הטקסט.

הפחתת המעבר בין הגופן החלופי לבין גופן האינטרנט

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

סיכום

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