ניראות (content-visiability): נכס ה-CSS החדש שמשפר את ביצועי הרינדור

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

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

הדגמה עם דמויות שמייצגות את תוצאות הרשת
בהדגמה במאמר שלנו, החלת content-visibility: auto על אזורי תוכן במקטעים משפרת את ביצועי הרינדור פי 7 בטעינה הראשונית. למידע נוסף, כדאי להמשיך לקרוא.

תמיכה בדפדפנים

תמיכה בדפדפן

  • 85
  • 85
  • 125
  • 18

מקור

content-visibility מסתמך על קווים ראשוניים בתוך בתוך ה-CSS מפרט. אומנם רק content-visibility נתמך כרגע ב-Chromium 85 (והוא מוגדר כ"ערך יצירת אב טיפוס" עבור Firefox), מפרטי הגבולות נתמכים בגרסה המודרנית ביותר דפדפנים.

עצירת תשלום של שירות CSS

המפתח והיעד הכללי של בלימת שירותי CSS הם לאפשר רינדור שיפורי ביצועים של תוכן אינטרנט באמצעות בידוד צפוי של תת-עץ של DOM משאר הדף.

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

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

  • size: בלימת הגודל של רכיב מבטיחה שתיבת הרכיב יכולה להיות ללא צורך לבחון את הצאצאים שלו. כלומר, אנחנו יכולים ניתן לדלג על פריסת הצאצאים אם כל מה שאנחנו צריכים הוא גודל לרכיב מסוים.
  • layout: בלימת הפריסה פירושה שצאצאים לא משפיעים על פריסה חיצונית של תיבות אחרות בדף. כך אנחנו יכולים לדלג על פריסת הצאצאים, אם כל מה שאנחנו רוצים לעשות הוא לפרוס תיבות אחרות.
  • style: הגבלת סגנון מבטיחה שמאפיינים שעשויים להשפיע על והם לא רק הצאצאים שלו לא יוצאים מהאלמנט (למשל מונה). הזה היא מאפשרת לנו לדלג על חישוב סגנון עבור הצאצאים, הוא רוצה לחשב סגנונות באלמנטים אחרים.
  • paint: בידוד צבע מבטיח שהצאצאים של התיבה שמכילה את האובייקט להופיע מחוץ לגבולות שלו. שום דבר לא יכול לחרוג באופן גלוי מהאלמנט, ואם רכיב מסוים נמצא מחוץ למסך או לא גלוי מסיבה אחרת, הצאצאים שלו גם לא גלויות. כך אנחנו יכולים לדלג על השלב הזה אם הרכיב נמצא מחוץ למסך.

מדלג על עבודה הרינדור עם content-visibility

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

המאפיין 'הרשאות גישה לתוכן' מקבל כמה ערכים, אבל auto הוא שמספק שיפורים מיידיים בביצועים. רכיב שכולל content-visibility: auto מקבל קליטה של layout, style ו-paint. אם המיקום אלמנט החיפוש נמצא מחוץ למסך (ולא רלוונטי למשתמש מסיבה אחרת - רלוונטי) הם אלו שבהם יש מיקוד או בחירה בעץ המשנה), גם מקבל גבול size (והוא מפסיק לפעול ציור וגם מבחן היטים את התוכן שלו).

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

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

הערה בנושא נגישות

אחת התכונות של content-visibility: auto היא שהתוכן שלא מוצג במסך נשאר זמין במודל האובייקטים של המסמך, ולכן עץ הנגישות (לא כמו ב-visibility: hidden). כלומר, ניתן לחפש את התוכן בדף ולנווט אליו, מבלי להמתין לטעינתו או לפגוע בביצועי העיבוד.

עם זאת, הצד ההפוך הוא שרכיבי ציון דרך עם תכונות סגנון כמו display: none או visibility: hidden יופיעו גם בעץ הנגישות כשהם מחוץ למסך, כי הדפדפן לא יציג את הסגנונות האלה עד שהם ייכנסו לאזור התצוגה. כדי שהן לא יופיעו בעץ הנגישות, וזה עלול לגרום לבלגן, מומלץ להוסיף גם את aria-hidden="true".

לדוגמה: בלוג בנושא טיולים

בדוגמה הזו אנחנו מחילים את הבלוג שלנו בנושא נסיעות בצד ימין, ומחילים את content-visibility: auto על אזורים במקטעי נתונים בצד שמאל. התוצאות מציגות זמני רינדור, שנעים בין 232 אלפיות השנייה ל-30 אלפיות שנייה בטעינה הראשונית של הדף.

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

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

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

צילום מסך של בלוג בנושא טיולים.
דוגמה לבלוג בנושא טיולים. לעיון בקטע הדגמה ב-Codepen

עכשיו כדאי לחשוב מה יקרה אם תוסיפו את content-visibility: auto לכל אחד סיפורים בודדים בבלוג. הלולאה הכללית זהה: הדפדפן מוריד ומעבד מקטעי דף. אבל ההבדל כמות העבודה שהוא עושה בשלב 2.

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

הביצועים של טעינת הדף הזה יהיו כאילו הם מכילים תוכן במסך מלא כתבות ותיבות ריקות עבור כל אחד מהסיפורים שמחוץ למסך. לביצועים האלה יש ביצועים טובים מאוד טוב יותר, עם ירידה צפויה של 50% או יותר מעלות הרינדור של בטעינה. בדוגמה שלנו, אנחנו רואים עלייה מזמן הרינדור של 232 אלפיות השנייה זמן רינדור 30 אלפיות השנייה. מדובר בשיפור של פי 7 בביצועים.

איזו עבודה צריך לעשות כדי ליהנות מיתרונות אלו? קודם כל, חלק את התוכן לחלקים:

צילום מסך עם הערות של קיבוץ התוכן לקטעים באמצעות מחלקה של CSS.
דוגמה לקיבוץ תוכן בקטעים שבהם הוחלה הכיתה story, כדי לקבל content-visibility: auto. לעיון בקטע הדגמה ב-Codepen

לאחר מכן מחילים את כלל הסגנון הבא על הקטעים:

.story {
  content-visibility: auto;
  contain-intrinsic-size: 1000px; /* Explained in the next section. */
}

ציון הגודל הטבעי של רכיב באמצעות contain-intrinsic-size

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

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

למרבה המזל, שירות ה-CSS מספק נכס נוסף, contain-intrinsic-size, מציין את הגודל הטבעי של הרכיב אם הרכיב מושפעות מכמות גדולה מדי. בדוגמה שלנו אנחנו מגדירים אותו בתור 1000px אומדן של הגובה והרוחב של הקטעים.

כלומר, הפריסה תתפרס כאילו היה לו צאצא יחיד בגודל אינטנסיבי" כדי להבטיח שקודי div ללא גודל עדיין תופסים מקום. contain-intrinsic-size משמש כגודל placeholder במקום תוכן שעבר רינדור.

ב-Chromium 98 ואילך, יש auto חדש מילת מפתח עבור contain-intrinsic-size. כשמצוין, הדפדפן יזכור גודל העיבוד האחרון, אם יש, ולהשתמש בו במקום ב-placeholder שסופק על ידי המפתח גודל. לדוגמה, אם ציינת את contain-intrinsic-size: auto 300px, יתחיל בגודל מהותי 300px בכל מאפיין, אבל ברגע התוכן של הרכיב עובר רינדור, הוא ישמור על הגודל הפנימי שעבר רינדור. כל שינוי נוסף בגודל העיבוד יישמר גם הוא. בפועל, המשמעות היא שאם לגלול רכיב עם content-visibility: auto ואז לגלול אותו חזרה מחוץ למסך, הוא ישמור אוטומטית על הרוחב והגובה האידיאליים שלו, לגודל של ה-placeholder. התכונה הזאת שימושית במיוחד לגלילה מתמשכת, מה שיכול לשפר באופן אוטומטי את הערכת הגודל לאורך זמן, מבקר בדף.

מסתיר תוכן באמצעות content-visibility: hidden

מה אם ברצונך להשאיר את התוכן ללא עיבוד, גם אם לא נמצא במסך, תוך מינוף היתרונות של מצב העיבוד שנשמר במטמון? מזינים: content-visibility: hidden

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

כך יש לך שליטה רבה יותר, ומאפשר לך להסתיר את התוכן ואת לבטל את ההסתרה שלהן מאוחר יותר.

ניתן להשוות זאת לדרכים נפוצות אחרות להסתרת תוכן של אלמנטים:

  • display: none: מסתיר את האלמנט ומשמיד את מצב העיבוד שלו. הזה המשמעות היא שביטול ההסתרה של האלמנט יהיה יקר כמו עיבוד של רכיב חדש עם אותם תכנים.
  • visibility: hidden: הסתרת הרכיב ושמירת מצב הרינדור שלו. הזה לא באמת מסיר את הרכיב מהמסמך, שכן הוא (והוא עץ המשנה) עדיין תופסת שטח גיאומטרי בדף ועדיין ניתן ללחוץ עליה. הוא גם מעדכן את מצב העיבוד בכל פעם שיש בו צורך, גם כשהוא מוסתר.

לעומת זאת, הרכיב content-visibility: hidden מסתיר את הרכיב בזמן לשמר את מצב העיבוד שלו, כך שאם יהיו שינויים הן מתרחשות רק כאשר הרכיב מוצג שוב (כלומר הנכס content-visibility: hidden הוסר).

דוגמאות לתרחישים טובים לדוגמה של content-visibility: hidden כאשר מטמיעים באמצעות גלילה וירטואלית מתקדמת ופריסה של מדידה. אפשר להשתמש בהם גם אפליקציות בדף יחיד (SPA). ניתן להשאיר תצוגות של אפליקציות לא פעילות ב-DOM עם content-visibility: hidden הוחל/ה כדי למנוע את התצוגה, אבל לשמור על הערך במצב של שמירה במטמון. כך התצוגה תעבור עיבוד מהיר כאשר היא תחזור להיות פעילה.

ההשפעות על אינטראקציה עד הצבע הבא (INP)

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

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

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

סיכום

content-visibility ומפרט הגבולות של CSS מציינים ביצועים מלהיבים ההגדלה מגיעות ישירות לקובץ ה-CSS. לקבלת מידע נוסף על נכסים, כדאי לבדוק: