למה חלק מהאנימציות איטיות?

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

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

סביר להניח שקצב פריימים של 60 FPS הוא היעד ליצירת אנימציות של תכנים באינטרנט. קצב הפריימים הזה מבטיח שהאנימציות ייראו חלקים. באינטרנט, פריים הוא הזמן שנדרש לביצוע כל העבודה הנדרשת לעדכון ולצביעה מחדש של המסך. אם כל פריים לא יושלם תוך 16.7 אלפיות השנייה (1,000 ms / 60 ≈ 16.7), המשתמשים יבחינו בעיכוב.

צינור עיבוד הנתונים

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

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

ארבעת השלבים האלה נקראים צינור עיבוד הנתונים של הדפדפן.

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

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

אנימציה של מאפייני פריסה

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

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

מאפייני צבע אנימציה

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

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

יצירת אנימציה של מאפיינים מרוכבים

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

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

מהי שכבה?

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

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

ביצועים של CSS לעומת ביצועים של JavaScript

ייתכן שתשאלו את השאלה הבאה: האם עדיף להשתמש ב-CSS או ב-JavaScript כדי ליצור אנימציות, מנקודת מבט של ביצועים?

אנימציות המבוססות על CSS ואנימציות באינטרנט (בדפדפנים שתומכים ב-API) מטופלות בדרך כלל בשרשור שנקרא שרשור המרכיב. היא שונה מה-thread הראשי של הדפדפן, שבו מבוצעות עיצוב, הפריסה, הציור ו-JavaScript. כלומר, אם הדפדפן מריץ משימות יקרות ב-thread הראשי, יכול להיות שהאנימציות ימשיכו לפעול בלי הפרעה.

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

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