שיפור המדד Largest Contentful Paint בסביבת JavaScript.
כחלק מפרויקט Aurora, Google עבדה עם מסגרות אינטרנט פופולריות כדי לוודא שהן מניבות ביצועים טובים בהתאם למדדים הבסיסיים של חוויית המשתמש (Core Web Vitals). כבר הוספנו את האפשרות להטמיע פונטים בקוד ב-Angular וב-Next.js, כפי שמוסבר בחלק הראשון של המאמר הזה. האופטימיזציה השנייה שנדבר עליה היא הטמעת CSS קריטי בקוד, שמופעל עכשיו כברירת מחדל ב-Angular CLI, ואנחנו עובדים על הטמעה שלו ב-Nuxt.js.
הטמעת גופן בקוד
אחרי ניתוח של מאות אפליקציות, צוות Aurora מצא שיזמים כוללים גופנים באפליקציות שלהם באמצעות הפניה אליהם ברכיב <head>
של index.html
. כך זה נראה כשכוללים את Material Icons:
<!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 ומ-Angular v11. בשתיהן יש תמיכה בהטמעת גופנים של Google ו-Adobe. Angular צפויה להשיק את התכונה הזו בגרסה 12.2.
אפשר למצוא את ההטמעה של הטמעת גופן ב-Next.js ב-GitHub, ולצפות בסרטון שמסביר את האופטימיזציה הזו בהקשר של Angular.
הטמעת CSS קריטי בקוד
שיפור נוסף כרוך בשיפור המדדים הצגת תוכן ראשוני (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 קריטי בקוד ה-HTML זמינה עכשיו ב-Angular ומופעל כברירת מחדל בגרסה 12. אם אתם משתמשים בגרסה 11, תוכלו להפעיל את התכונה על ידי הגדרת המאפיין inlineCritical
לערך true
בקובץ angular.json
. כדי להביע הסכמה לשימוש בתכונה הזו ב-Next.js, מוסיפים את experimental: { optimizeCss: true }
ל-next.config.js
.
מסקנות
בפוסט הזה התייחסנו לחלק מהשיתוף הפעולה בין Chrome לבין מסגרות אינטרנט. אם אתם מחברי מסגרות ותזהו חלק מהבעיות שטיפלנו בהן בטכנולוגיה שלכם, אנחנו מקווים שהממצאים שלנו יעודדו אתכם ליישם אופטימיזציות דומות של ביצועים.
מידע נוסף על השיפורים רשימה מקיפה של עבודות האופטימיזציה שעשינו בנושא מדדי חוויית המשתמש הבסיסיים מופיעה במאמר אנחנו גאים להציג את Aurora.