שיפור המדד Largest Contentful Paint בסביבת JavaScript.
כחלק מפרויקט Aurora, Google עבדה עם מסגרות אינטרנט פופולריות כדי לוודא שהן מניבות ביצועים טובים בהתאם למדדים הבסיסיים של חוויית המשתמש (Core Web Vitals). כבר הוספנו את האפשרות להטמיע פונטים בקוד ב-Angular וב-Next.js, כפי שמוסבר בחלק הראשון של המאמר. האופטימיזציה השנייה שנעסוק בה היא הטמעת CSS חיונית, שמופעלת עכשיו כברירת מחדל ב-Agular CLI ושנמצאת בשלבי הטמעה ב-Nuxt.js.
הטמעת גופן בקוד
אחרי ניתוח של מאות אפליקציות, צוות Aurora מצא שיזמים כוללים גופנים באפליקציות שלהם לעיתים קרובות על ידי הפניה אליהם ברכיב <head>
של index.html
. הדוגמה הבאה ממחישה איך זה ייראה כשכוללים Material Icon:
<!doctype html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
...
</html>
אמנם התבנית הזו תקינה ופועלת בצורה מלאה, אבל היא חוסמת את העיבוד של האפליקציה ומוסיפה בקשה נוספת. כדי להבין טוב יותר מה קורה, כדאי לעיין בקוד המקור של גיליון הסגנונות שאליו מתייחס ה-HTML שלמעלה:
/* fallback */
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/font.woff2) format('woff2');
}
.material-icons {
/*...*/
}
שימו לב שההגדרה של font-face
מפנה לקובץ חיצוני שמתארח ב-fonts.gstatic.com
.
כשהאפליקציה נטענת, הדפדפן צריך קודם להוריד את גיליון הסגנונות המקורי שמוזכר בכותרת.
לאחר מכן, הדפדפן מוריד את הקובץ woff2
, ובסופו של דבר הוא יכול להמשיך ברינדור של האפליקציה.
הזדמנות לאופטימיזציה היא להוריד את גיליון הסגנונות הראשוני בזמן ה-build ולהוסיף אותו ל-index.html
. כך אפשר לדלג על נסיעה הלוך ושוב שלמה ל-CDN בזמן הריצה, וכך לקצר את זמן החסימה.
כשמפתחים את האפליקציה, נשלחת בקשה ל-CDN, שמאחזר את גיליון הסגנונות ומוסיף אותו לקובץ ה-HTML, תוך הוספת <link rel=preconnect>
לדומיין. אם נשתמש בשיטה הזו, נקבל את התוצאה הבאה:
<!doctype html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin >
<style type="text/css">
@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/font.woff2) format('woff2');}.material-icons{/*...*/}</style>
...
</html>
הטמעת גופנים בקוד זמינה עכשיו ב-Next.js וב-Angular
כשמפתחי המסגרות מטמיעים אופטימיזציה בכלים הבסיסיים, קל יותר להפעיל אותה באפליקציות קיימות וחדשות, וכך לשפר את כל הסביבה העסקית.
השיפור הזה מופעל כברירת מחדל מ-Next.js v10.2 ומ-Agular v11. בשתיהן יש תמיכה בהטמעת גופנים של Google ו-Adobe. Angular צפויה להשיק את האפשרות השנייה בגרסה 12.2.
אפשר למצוא את ההטמעה של הטמעת גופן ב-Next.js ב-GitHub, ולצפות בסרטון שמסביר את האופטימיזציה הזו בהקשר של Angular.
הטמעת CSS קריטי בקוד
כדי לשפר את התוצאות, אפשר לשפר את המדדים First Contentful Paint (FCP) ו-LCP) באמצעות סימון של רכיבי CSS קריטיים. ה-CSS הקריטי של דף כולל את כל הסגנונות שנעשה בהם שימוש ברינדור הראשוני שלו. מידע נוסף על הנושא זמין במאמר דחיית CSS לא קריטי.
שמנו לב שאפליקציות רבות טוענות סגנונות באופן סינכרוני, מה שגורם לחסימה של עיבוד האפליקציה. פתרון מהיר הוא לטעון את הסגנונות באופן אסינכרוני. במקום לטעון את הסקריפטים באמצעות media="all"
, מגדירים את הערך של המאפיין media
כ-print
, ולאחר השלמת הטעינה מחליפים את ערך המאפיין ל-all
:
<link rel="stylesheet" href="..." media="print" onload="this.media='all'">
עם זאת, השיטה הזו עלולה לגרום להבהוב של תוכן לא מעוצב.
בסרטון שלמעלה מוצגת העיבוד (ה-rendering) של דף, שבו הטעינה של הסגנונות מתבצעת באופן אסינכרוני. ההבהוב מתרחש כי הדפדפן מתחיל קודם להוריד את הסגנונות, ואז מעבד את ה-HTML שמגיע אחריו. אחרי שהדפדפן מוריד את הסגנונות, הוא מפעיל את האירוע onload
של רכיב הקישור, מעדכן את המאפיין media
לערך all
ומחיל את הסגנונות על ה-DOM.
במהלך פרק הזמן שבין עיבוד ה-HTML להחלת הסגנונות, העיצוב של הדף בוטל באופן חלקי. כשהדפדפן משתמש בסגנונות, אנחנו רואים הבהוב, שחוויית המשתמש שלו גרועה והוא גורם לרגרסיות בשינוי מצטבר של הפריסה (CLS).
הטמעת קוד CSS קריטי, יחד עם טעינת סגנונות באופן אסינכרוני, יכולים לשפר את התנהגות הטעינה. הכלי critters מוצא את הסגנונות שבהם נעשה שימוש בדף על ידי בדיקה של הבוררים בגיליון סגנונות והתאמתם ל-HTML. כשהמערכת מוצאת התאמה, היא מתייחסת לסגנונות התואמים כחלק מה-CSS הקריטי ומטמיעה אותם בקוד.
נבחן את הדוגמה הבאה:
<head> <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'"> </head> <body> <section> <button class="primary"></button> </section> </body>
/* styles.css */ section button.primary { /* ... */ } .list { /* ... */ }
בדוגמה שלמעלה, המערכת תקריא ותנתח את התוכן של styles.css
, ואז תתאים את שני הבוררים ל-HTML ותגלה שאנחנו משתמשים ב-section button.primary
.
לבסוף, ה-critters יציגו את הסגנונות התואמים ב-<head>
של הדף, וכתוצאה מכך:
<head> <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'"> <style> section button.primary { /* ... */ } </style> </head> <body> <section> <button class="primary"></button> </section> </body>
אחרי שמזינים את קוד ה-CSS הקריטי ב-HTML, אפשר לראות שההבהוב של הדף נעלם:
הטמעת CSS קריטי בקוד זמינה עכשיו ב-Angular ומופעל כברירת מחדל בגרסה 12. אם אתם משתמשים בגרסה 11,
כדי להפעיל אותה, צריך להגדיר את inlineCritical
כ-true
ב-angular.json
. כדי להביע הסכמה לשימוש בתכונה הזו ב-Next.js, מוסיפים את experimental: { optimizeCss: true }
ל-next.config.js
.
מסקנות
בפוסט הזה התייחסנו לחלק משיתוף הפעולה בין Chrome לבין frameworks באינטרנט. אם אתם מחברי מסגרות ותזהו חלק מהבעיות שטיפלנו בהן בטכנולוגיה שלכם, אנחנו מקווים שהממצאים שלנו יעודדו אתכם ליישם אופטימיזציות דומות של ביצועים.
מידע נוסף על השיפורים רשימה מקיפה של עבודות האופטימיזציה שעשינו בנושא מדדי חוויית המשתמש הבסיסיים מופיעה במאמר אנחנו גאים להציג את Aurora.