איך יוצרים אנימציות CSS עם ביצועים גבוהים

במדריך הזה מוסבר איך ליצור אנימציות CSS בעלות ביצועים גבוהים.

במאמר למה חלק מהאנימציות איטיות? מוסבר מה עומד מאחורי ההמלצות האלה.

תאימות דפדפן

לכל מאפייני ה-CSS המומלצים במדריך הזה יש תמיכה טובה בדפדפנים שונים.

transform

תמיכה בדפדפן

  • Chrome:‏ 36.
  • Edge:‏ 12.
  • Firefox: 16.
  • Safari: 9.

מקור

opacity

תמיכה בדפדפן

  • Chrome:‏ 1.
  • Edge:‏ 12.
  • Firefox:‏ 1.
  • Safari: 2.

מקור

will-change

תמיכה בדפדפן

  • Chrome:‏ 36.
  • Edge:‏ 79.
  • Firefox: 36.
  • Safari: 9.1.

מקור

העברת רכיב

כדי להעביר רכיב, משתמשים בערכי מילות המפתח translate או rotation של המאפיין transform.

לדוגמה, כדי להציג פריט, משתמשים במקש translate.

.animate {
  animation: slide-in 0.7s both;
}

@keyframes slide-in {
  0% {
    transform: translateY(-1000px);
  }
  100% {
    transform: translateY(0);
  }
}

משתמשים ב-rotate כדי לסובב רכיבים. בדוגמה הבאה מוצגת סיבוב של רכיב ב-360 מעלות.

.animate {
  animation: rotate 0.7s ease-in-out both;
}

@keyframes rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

שינוי הגודל של רכיב

כדי לשנות את גודל הרכיב, משתמשים בערך scale של מילת המפתח במאפיין transform.

.animate {
  animation: scale 1.5s both;
}

@keyframes scale {
  50% {
    transform: scale(0.5);
  }
  100% {
    transform: scale(1);
  }
}

שינוי הרשאות הגישה של רכיב

כדי להציג או להסתיר רכיב, אפשר להשתמש בסמל opacity.

.animate {
  animation: opacity 2.5s both;
}

@keyframes opacity {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

נמנעים ממאפיינים שמפעילים פריסה או צבע

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

אילוץ יצירת שכבה

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

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

ב-CSS, אפשר להחיל את will-change על כל סלקטור:

body > .sidebar {
  will-change: transform;
}

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

אם רוצים לאלץ יצירת שכבות בדפדפן שלא תומך ב-will-change (סביר להניח ש-Internet Explorer), אפשר להגדיר את transform: translateZ(0).

ניפוי באגים באנימציות איטיות או עם בעיות

בכלי הפיתוח ל-Chrome ובכלי הפיתוח ל-Firefox יש המון כלים שיעזרו לכם להבין למה האנימציות איטיות או איטיות.

איך בודקים אם אנימציה מפעילה פריסה

אנימציה שמזיזה רכיב באמצעות משהו אחר מ-transform צפויה להיות איטית. בדוגמה הבאה מוצגת השוואה בין אנימציה שמשתמשת ב-transform לבין אנימציה שמשתמשת ב-top וב-left.

מה אסור לעשות
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     top: calc(90vh - 160px);
     left: calc(90vw - 200px);
  }
}
מה מותר לעשות
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     transform: translate(calc(90vw - 200px), calc(90vh - 160px));
  }
}

אפשר לבדוק את זה בשתי הדוגמאות הבאות ב-Glitch, ולבחון את הביצועים באמצעות DevTools.

כלי פיתוח ל-Chrome

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

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

בחלונית Summary מוצגים 37 אלפיות השנייה לעיבוד ו-79 אלפיות השנייה לציור.
הקוד לדוגמה animation-with-top-left גורם לעיבוד (רינדור).
בחלונית Summary מוצגים ערכים אפס לעיבוד ויצירת תמונה.
הדוגמה animation-with-transform לא גורמת לעיבוד תמונה.

Firefox DevTools

ב-Firefox DevTools, התרשים Waterfall יכול לעזור לכם להבין איפה הדפדפן מבזבז זמן.

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

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

בדיקה אם יש ירידה בכמות הפריימים

  1. פותחים את הכרטיסייה עיבוד בכלי הפיתוח ל-Chrome.
  2. מסמנים את התיבה מדד FPS.
  3. צפייה בערכים בזמן האנימציה פועלת.

חשוב לשים לב לתווית פריימים בחלק העליון של ממשק המשתמש של מד ה-FPS. כאן מוצגים ערכים כמו 50% 1 (938 m) dropped of 1878. לאנימציה עם ביצועים גבוהים יש אחוז גבוה, למשל 99%, כלומר יש פחות פריימים שנמחקים והאנימציה נראית חלקה.

במד קצב הפריימים רואים 50% מהפריימים הוסרו
בדוגמה animation-with-top-left, 50% מהפריימים נמחקים
מד ה-FPS מראה שרק 1% מהפריימים הושמטו
בדוגמה animation-with-transform, רק 1% מהפריימים נמחקים.

בדיקה אם אנימציה מפעילה ציור

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

כלי פיתוח ל-Chrome

  1. פותחים את הכרטיסייה רינדור בכלי הפיתוח ל-Chrome.
  2. בוחרים באפשרות Paint Flashing.
  3. מזיזים את הסמן מסביב למסך.
רכיב בממשק המשתמש שמודגש בירוק כדי להראות שהוא ייצבע מחדש
בדוגמה הזו ממפות Google אפשר לראות את הרכיבים שצוירו מחדש.

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

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

Firefox DevTools

  1. פותחים את Settings (הגדרות) ומוסיפים את לחצן ארגז הכלים של Toggle Paint flash.
  2. בדף שרוצים לבדוק, מפעילים את הלחצן ומזיזים את העכבר או גוללים כדי לראות את האזורים המודגשים.

סיכום

במידת האפשר, כדאי להגביל את האנימציות ל-opacity ול-transform כדי שהן יישארו בשלב הרכבת התמונות (compositing) של נתיב העיבוד. אפשר להשתמש בכלי הפיתוח כדי לבדוק איזה שלב בנתיב מושפע מהאנימציות.

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

כדאי להשתמש במאפיין will-change באופן מוגבל, ורק אם נתקלתם בבעיה בביצועים.