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

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

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

  • עיבוד טקסט מאוחר: אם גופן אינטרנט לא נטען, דפדפנים בדרך כלל מעכבים את עיבוד הטקסט. במצבים רבים, עיכוב של הצגת תוכן ראשוני (FCP). במצבים מסוימים, הפעולה הזו מעכבת את הנתונים של Largest Contentful Paint (LCP).
  • שינויי פריסה: הפעולה של החלפת גופנים עשויה לגרום לתנודות בפריסה, ולכן יש להן השפעה על Cumulative Layout Shift (CLS). שינויי הפריסה האלה מתרחשים כשגופן אינטרנט והגופן החלופי שלו תופסים כמויות שונות של שטח בדף.

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

הגופן בטעינה

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

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

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

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

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

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

שליחת גופנים

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

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

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

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

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

שימוש ב-WOFF2

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

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

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

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

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

סיכום

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