חיפוש ]

שיפור מהירות טעינת Google Fonts באמצעות preconnect

Google Fonts הוא שירות די אמין וניתן לומר כי ביצועי הרשת שלו מאד טובים – הוא מסתמך כמובן על ה CDN הגלובלי של גוגל. עם זאת, הפעולה הפשוטה של ייזום בקשת HTTP לאותם פונטים יכולה לגרום ל Round Trip Times – RTT מיותרים לפני שהבקשה בפועל מנותבת לשרת וזאת מכיוון שעל הדפדפן לבצע מספר פעולות לפני שהבקשה מגיעה לשרת:

  • Resolving DNS
  • Performing TCP handshake
  • Negotiating TLS Tunnel – אם מדברים על בקשת HTTPS

לא נרחיב במאמר זה על פעולות אלו, אך אותן פעולות (אליהן נתייחס כ DNS, TCP, TLS), משמעותן בין אחד לשלושה RTT הגורמים לעיכוב (latency) לפני שהבקשה עצמה מנותבת לשרת.

דפדפנים מודרנים, מנסים בכל כוחם לחזות אילו חיבורים נדרשים לפני שהבקשה לשרת מתבצעת בפועל. הדפדפן מנסה לפתוח את החיבורים הדרושים לפני שהבקשה לשרת מתבצעת על ידי ייזום preconnect לדומיינים מסויימים ובכך לבטל RTT יקרים של אותן בקשות מחלקו הקריטי העליון  של העמוד (Critical Path).

למרות זאת, וככל שדפדפנים חכמים בימינו, הם לא יכולים לחזות בוודאות את כל הדומיינים להן preconnect יעזור בכל אתר ואתר.

החדשות הטובות הן שאנו יכולים לעזור לדפדפן במקרים אלו ובעצם לומר לו אילו דומיינים (נכון יותר לומר אילו sockets) אנו רוצים לפתוח לפני הבקשות עצמן בעזרתpreconnect hint הלא הוא rel="preconnect".

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

לפני שנמשיך נאמר כי ניתן להשתמש בפעולה אף יותר ״אגרסיבית״ מ preconnect הנקראית preload וכנראה וזו עדיפה על preconnect לטובת פונטים. השתמשו ב preload יחד עם הגדרה נכונה של font-display ואתם מסודרים מבחינה זו.

שימו לב שעליכם להשתמש ב preload ולא ב preconnect אם אתם טוענים את Google Fonts לוקאלית מהשרת שלכם.

מה הבעיה בטעינה סטנדרטית של google fonts?

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

google-fonts-no-preconnect
שימו לב כי בגרף זה, הדפדפן מושך את ה html ומגלה כי הוא צריך נכס css כלשהוא שנמצא בדומיין fonts.gogleapis.com. כאשר מסיים להוריד css זה בונה את ה CSSOM ומבין כי לעמוד זה דרושים מספר פונטים אז יוזם בקשות לכל אחד מהן מהדומיין fonts.gstatic.com.

קודם לכן, כמובן שהוא חייב לבצע את התהליך שהראינו קודם והוא DNS, TCP & TLS ולכן, רק ברגע שסיים הבקשות יתקבלו ב multiplexing על גבי חיבור ה HTTP/2.

<link href='https://fonts.gstatic.com' rel='preconnect' crossorigin>
<link href="https://fonts.googleapis.com/css?family=Assistant:300,400,700,800" rel="stylesheet">

נוסיף את הקוד מעלה לבלוג זה והנה התוצאה:

google-fonts-preconnect

בגרף זה לעומת זאת, אנו מוסיפים preconnect hint למשוואה שאומר לדפדפן כי בכוונתו של אתר זה למשוך נכסים מסויימים מהדומיין fonts.static.com. כתוצאה מכך, הדפדפן יתחיל בפתיחת החיבור במקביל עם הקריאה לנכס ה css ויסיים זאת מוקדם יותר. ברגע שיגיע לקריאה לפונטים לא יהיו עכבות והוא יטען את הפונטים מיידית!

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

מכיוון וכולנו אוהבים וורדפרס, הנה הדרך להוסיף preconnect כשטוענים google fonts בוורדפרס, שימו לב לשורה 7 בה קבענו כי העדיפות להוק זה תהיה הכי גבוהה על ידי הוספה של המספר 0 ב add_action.

<?php
// BEGIN HERE //
function savvy_preconnect() { ?>
    <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
<?php
}
add_action('wp_head', 'savvy_preconnect', 0);

google fonts משתמשים ב fonts-face@, ומכיוון והספסיפיקציות של אלו דורשות כי הקריאות יבוצעו ״בצורה אנונימית״, יש להוסיף את התכונה crossorigin ל preconnect hint שביצענו.

מה לגבי תמיכת דפדפנים?

preconnect נתמך בכרום ופיירפורס כבר הרבה זמן אך עם זאת איני רואה שימוש רחב באפשרות זו, במיוחד באתרים בארץ. נכון לציין אגב שלדפדפנים ישנה היכולות להחליט כיצד להתייחס לפעולה זו (לכן היא היא נקראית preconnect hint); באפשרות הדפדפן להחליט כי הוא יבצע רק חלק מפעולות ה DNS, TCP, TLS לבחירתו וזהו גם ה fallback בדפדפנים שאינם תומכים באפשרות זו.

אז לגבי תמיכת דפדפנים, אלו הגירסאות של הדפדפנים התומכים:

Data on support for the link-rel-preconnect feature across the major browsers from caniuse.com

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

השתמשו ב preconnect בחוכמה

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

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

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

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

מאחר ואני צולל לעולם זה לאחרונה, תתכוננו גם למאמרים בנושא dns-prefetch, preload & prerender בין היתר בזמן הקרוב  🙂 תרגישו חופשי לשתף מחשבות (ולשתף את המאמר!) על הדרך…

  • אליסף 31 אוקטובר 2017, 8:23

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

  • מאור 7 נובמבר 2017, 15:53

    מוסיפים את זה לקובץ function?

  • צבי חזנוב 20 יוני 2019, 10:59

    ניסיתי להוסיף את הקוד ל functions.php של HELLO THEME של אלמנטור אבל זה לא עבד (האתר הפסיק לעלות ונאלצתי למחוק את הקוד כדי שיחזור לפעול). מה יכל לגרום לזה?

    • רועי יוסף 20 יוני 2019, 11:17

      היי צבי, שים לב שאינך מוסיף את תגית ה PHP הפותחת..

תגובה חדשה

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

Savvy WordPress Development