הורדה של WebFont "מלא" שכולל את כל הווריאציות הסגנוניות, שאולי לא תצטרכו, וגם את כל הגליפים, שאולי לא ישמשו אתכם, יכולה בקלות להגיע לכמה מגה-בייט. במאמר הזה נסביר איך לבצע אופטימיזציה של טעינת WebFonts כדי שהמבקרים יורידו רק את מה שהם ישתמשו בו.
כדי לטפל בבעיה של קובצי CSS גדולים שמכילים את כל הווריאציות, כלל ה-CSS @font-face
תוכנן במיוחד כדי לאפשר לכם לפצל את משפחת הגופנים לאוסף של משאבים. לדוגמה, קבוצות משנה של Unicode וריאציות סגנון נפרדות.
על סמך ההצהרות האלה, הדפדפן מחשב את הקבוצות המשניות והוריאנטים הנדרשים ומוריד את הקבוצה המינימלית הנדרשת כדי להציג את הטקסט, וזה מאוד נוח. עם זאת, אם לא תהיו זהירים, היא עלולה גם ליצור צוואר בקבוק בביצועים בנתיב העיקרי לעיבוד ולעכב את העיבוד של הטקסט.
התנהגות ברירת המחדל
טעינה איטית של גופנים נושאת משמעות נסתרת חשובה שעלולה לעכב את העיבוד של הטקסט. הדפדפן צריך ליצור את עץ הרינדור, שמבוסס על עצי ה-DOM ו-CSSOM, כדי לדעת אילו משאבי גופנים נדרשים כדי להציג את הטקסט. כתוצאה מכך, בקשות לגופנים מתעכבות הרבה אחרי בקשות למשאבים קריטיים אחרים, ויכול להיות שהדפדפן לא יוכל להציג טקסט עד שהמשאב ייאוחזר.
- הדפדפן מבקש את מסמך ה-HTML.
- הדפדפן מתחיל לנתח את התשובה ב-HTML ולבנות את ה-DOM.
- הדפדפן מזהה קובצי CSS, JS ומשאבים אחרים ושולח בקשות.
- הדפדפן יוצר את ה-CSSOM אחרי שכל תוכן ה-CSS מתקבל, ומשלב אותו עם עץ ה-DOM כדי ליצור את עץ הרינדור.
- בקשות לגופנים נשלחות אחרי ש-tree ה-render מציין אילו וריאנטים של גופן נדרשים כדי להציג את הטקסט שצוין בדף.
- הדפדפן מבצע את הפריסה ומציג את התוכן במסך.
- אם הגופן עדיין לא זמין, יכול להיות שהדפדפן לא ירנדר פיקסלים של טקסט.
- אחרי שהגופן זמין, הדפדפן מצייר את הפיקסלים של הטקסט.
'המירוץ' בין הצביעה הראשונה של תוכן הדף, שיכולה להתבצע זמן קצר אחרי יצירת עץ העיבוד, לבין הבקשה למשאב הגופן, הוא הגורם ל'בעיית הטקסט הריק', שבה הדפדפן עשוי לעבד את פריסת הדף אבל להשמיט את הטקסט.
אם תטעינו מראש גופנים של WebFonts ותשתמשו ב-font-display
כדי לקבוע איך הדפדפנים יפעלו עם גופנים שאינם זמינים, תוכלו למנוע דפים ריקים ושינויי פריסה שנובעים מעומס בזמן הטעינה של הגופנים.
טעינה מראש של משאבי WebFont
אם יש סבירות גבוהה שהדף שלכם יצטרך WebFont ספציפי שמתארח בכתובת URL שאתם יודעים מראש, תוכלו להשתמש בתעדוף משאבים.
שימוש ב-<link rel="preload">
יגרום להפעלת בקשה ל-WebFont בשלב מוקדם של נתיב העיבוד הקריטי, בלי צורך להמתין ליצירת ה-CSSOM.
התאמה אישית של עיכוב הרינדור של הטקסט
טעינת נכסים מראש מגדילה את הסיכוי ש-WebFont יהיה זמין כשהתוכן של הדף יומר, אבל אין ערובה לכך.
עדיין צריך להביא בחשבון את האופן שבו דפדפנים מתנהגים כשהם מייצרים טקסט שמשתמש ב-font-family
שעדיין לא זמין.
בפוסט הימנעות מטקסט בלתי נראה במהלך טעינת הגופן אפשר לראות שההתנהגות שמוגדרת כברירת מחדל בדפדפנים לא עקבית.
עם זאת, אתם יכולים להגדיר את ההתנהגות של דפדפנים מודרניים באמצעות font-display
.
בדומה להתנהגויות הקיימות של זמן קצוב לתפוגה של גופן שחלק מהדפדפנים מטמיעים, font-display
מפלח את משך החיים של הורדת גופן לשלושה תקופות עיקריות:
- התקופה הראשונה היא התקופה של חסימה של גופן. במהלך התקופה הזו, אם סוג הגופן לא נטען, כל רכיב שמנסה להשתמש בו צריך להשתמש במקום זאת בסוג גופן חלופי בלתי נראה. אם פונט הפנים נטען בהצלחה במהלך תקופת החסימה, המערכת תשתמש בו באופן רגיל.
- תקופת החלפת הגופן מתרחשת מיד אחרי תקופת החסימה של הגופן. במהלך התקופה הזו, אם סוג הגופן לא נטען, כל רכיב שמנסה להשתמש בו צריך להשתמש במקום זאת בסוג גופן חלופי. אם סוג הגופן נטען בהצלחה במהלך תקופת ההחלפה, המערכת תשתמש בו באופן רגיל.
- תקופת כשל הגופן מתרחשת מיד אחרי תקופת החלפת הגופן. אם משפחת הגופן עדיין לא נטענת כשהתקופות האלה מתחילות, היא מסומנת כטעינה שנכשלה, וכתוצאה מכך מתבצעת החלפה רגילה לגופן חלופי. אחרת, נעשה שימוש בגופן באופן רגיל.
הבנת התקופות האלה מאפשרת לכם להשתמש ב-font-display
כדי לקבוע איך הגופן ייגרם, בהתאם למועד שבו הוא הורדה או לא הורדה.
כדי לעבוד עם הנכס font-display
, מוסיפים אותו לכללי @font-face
:
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 400;
font-display: auto; /* or block, swap, fallback, optional */
src: local('Awesome Font'),
url('/fonts/awesome-l.woff2') format('woff2'), /* will be preloaded */
url('/fonts/awesome-l.woff') format('woff'),
url('/fonts/awesome-l.ttf') format('truetype'),
url('/fonts/awesome-l.eot') format('embedded-opentype');
unicode-range: U+000-5FF; /* Latin glyphs */
}
בשלב הזה יש תמיכה ב-font-display
בטווח הערכים הבא:
auto
block
swap
fallback
optional
מידע נוסף על טעינה מראש של גופנים ועל המאפיין font-display
זמין בפוסטים הבאים:
- הימנעות מטקסט בלתי נראה במהלך טעינת הגופן
- שליטה בביצועי הגופן באמצעות font-display
- מניעת שינויי פריסה והבהובים של טקסט בלתי נראה (FOIT) באמצעות טעינת גופנים אופציונליים מראש
Font Loading API
כשמשתמשים ב-<link rel="preload">
וב-CSS font-display
ביחד, אפשר לשלוט במידה רבה בעומס העלויות של טעינת הגופן והעיבוד שלו, בלי להוסיף הרבה עלויות נוספות.
עם זאת, אם אתם צריכים התאמות אישיות נוספות, ואתם מוכנים לשאת בעלויות הנוספות של הפעלת JavaScript, יש לכם אפשרות אחרת.
Font Loading API מספק ממשק סקריפטים להגדרה ולמניפולציה של סוגים של גופנים ב-CSS, למעקב אחר התקדמות ההורדה שלהם ולביטול ברירת המחדל של התנהגות הטעינה האיטית. לדוגמה, אם אתם בטוחים שדרושה וריאנט מסוים של גופן, תוכלו להגדיר אותו ולהורות לדפדפן להתחיל אחזור מיידי של משאב הגופן:
var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});
// don't wait for the render tree, initiate an immediate fetch!
font.load().then(function() {
// apply the font (which may re-render text and cause a page reflow)
// after the font has finished downloading
document.fonts.add(font);
document.body.style.fontFamily = "Awesome Font, serif";
// OR... by default the content is hidden,
// and it's rendered after the font is available
var content = document.getElementById("content");
content.style.visibility = "visible";
// OR... apply your own render strategy here...
});
בנוסף, מכיוון שאפשר לבדוק את סטטוס הגופן (באמצעות השיטה check()
) ולעקוב אחרי התקדמות ההורדה שלו, אפשר גם להגדיר אסטרטגיה מותאמת אישית לעיבוד טקסט בדפים:
- אפשר להשהות את כל העיבוד של הטקסט עד שהגופן יהיה זמין.
- אפשר להטמיע זמן קצוב מותאם אישית לכל גופן.
- אפשר להשתמש בגופן החלופי כדי לבטל את החסימה של העיבוד ולהחדיר סגנון חדש שמשתמש בגופן הרצוי אחרי שהגופן יהיה זמין.
הכי טוב: אפשר גם לשלב בין האסטרטגיות שלמעלה לתוכן שונה בדף. לדוגמה, אפשר לעכב את העיבוד של הטקסט בחלקים מסוימים עד שהגופן יהיה זמין, להשתמש בגופן חלופי ואז לבצע עיבוד מחדש אחרי שההורדה של הגופן תסתיים.
חובה להשתמש במטמון בצורה נכונה
משאבי גופנים הם בדרך כלל משאבים סטטיים שלא מתעדכנים לעיתים קרובות. לכן, הם מתאימים במיוחד לתוקף תפוגה ארוך של max-age. חשוב לציין גם כותרת מותנית של ETag וגם מדיניות אופטימלית של Cache-Control לכל משאבי הגופנים.
אם אפליקציית האינטרנט שלכם משתמשת בסוכנות שירות, הצגת משאבי גופנים באמצעות אסטרטגיית שמירת מטמון קודם מתאימה לרוב התרחישים לדוגמה.
לא מומלץ לאחסן גופנים באמצעות localStorage
או IndexedDB, כי לכל אחת מהשיטות האלה יש בעיות ביצועים משלה.
מטמון ה-HTTP של הדפדפן מספק את המנגנון הטוב והעמיד ביותר להעברת משאבי גופנים לדפדפן.
רשימת משימות לטעינת WebFont
- התאמה אישית של טעינת הגופן והעיבוד שלו באמצעות
<link rel="preload">
,font-display
או Font Loading API: התנהגות ברירת המחדל של טעינת נכסים בזמן אמת עלולה לגרום לעיכוב בעיבוד הטקסט. התכונות האלה בפלטפורמת האינטרנט מאפשרות לשנות את ההתנהגות הזו לגבי גופנים מסוימים, ולציין שיטות עיבוד וסף זמן קצוב מותאמים אישית לתוכן שונה בדף. - ציון מדיניות לאימות חוזר ולאחסון אופטימלי במטמון: גופנים הם משאבים סטטיים שמתעדכנים לעיתים רחוקות. חשוב לוודא שהשרתים מספקים חותמת זמן לטווח ארוך עם תאריך תפוגה מקסימלי ואסימון לאימות מחדש, כדי לאפשר שימוש יעיל בגופן בין דפים שונים. אם אתם משתמשים ב-service worker, כדאי להשתמש בשיטה של אחסון במטמון קודם.
בדיקה אוטומטית של התנהגות טעינת WebFont באמצעות Lighthouse
Lighthouse יכול לעזור לכם להפוך את התהליך של בדיקת התאימות לשיטות המומלצות לאופטימיזציה של גופנים באינטרנט לאוטומציה.
הבדיקות הבאות יכולות לעזור לכם לוודא שהדפים שלכם ממשיכים לפעול בהתאם לשיטות המומלצות לאופטימיזציה של גופנים לאינטרנט לאורך זמן: