דפדפנים מודרניים יכולים להוסיף אנימציה לשני מאפייני CSS בזול: transform
ו-opacity
.
אם תוסיפו אנימציה לפריט אחר, סביר להניח שלא תגיעו לקצב של 60 פריימים לשנייה (FPS).
בפוסט הזה מוסבר למה זה קורה.
ביצועי אנימציה וקצב פריימים
מקובל לחשוב שקצב פריימים של 60FPS הוא היעד כשמפעילים אנימציה באינטרנט. שיעור הפריימים הזה יבטיח שהאנימציות ייראו חלקות. באינטרנט, פריים הוא הזמן שנדרש לביצוע כל העבודה הנדרשת לעדכון ולצביעה מחדש של המסך. אם כל פריים לא יושלם תוך 16.7 אלפיות השנייה (1,000 אלפיות השנייה / 60 ≈ 16.7), המשתמשים יבחינו בהשהיה.
צינור העיבוד ליצירת הגרפיקה
כדי להציג משהו בדף אינטרנט, הדפדפן צריך לבצע את השלבים הבאים ברצף:
- סגנון: חישוב הסגנונות שחלים על הרכיבים.
- פריסה: יצירת הגיאומטריה והמיקום של כל רכיב.
- צביעה: מילוי הפיקסלים של כל רכיב.
- שילוב: הפרדת הרכיבים לשכבות וציור השכבות במסך.
ארבעת השלבים האלה נקראים צינור עיבוד הנתונים לעיבוד (rendering) של הדפדפן.
כשאתם יוצרים אנימציה של משהו בדף שכבר נטען, צריך לבצע שוב את השלבים האלה. התהליך מתחיל מהשלב שצריך לשנות כדי לאפשר את האנימציה.
כפי שצוין קודם, השלבים האלה כרונולוגיים. לדוגמה, אם תוסיפו אנימציה למשהו שמשנה את הפריסה, גם השלבים של הצביעה והשילוב יצטרכו לפעול שוב. לכן, אנימציה של משהו שמשנה את הפריסה היא יקרה יותר מאנימציה של משהו שמשנה רק את השילוב.
אנימציה של מאפייני פריסה
שינויים בפריסה כוללים חישוב של הגיאומטריה (המיקום והגודל) של כל הרכיבים שהושפעו מהשינוי.
אם משנים רכיב אחד, יכול להיות שיהיה צורך לחשב מחדש את הגיאומטריה של רכיבים אחרים.
לדוגמה, אם משנים את הרוחב של האלמנט <html>
, כל אחד מהצאצאים שלו עשוי להיות מושפע.
בגלל האופן שבו רכיבים חורגים מעבר למסגרת ומשפיעים זה על זה, לפעמים שינויים בהמשך העץ יכולים לגרום לחישוב מחדש של הפריסה עד לחלק העליון.
ככל שעץ הרכיבים הגלויים גדול יותר, כך זמן החישוב של הפריסה ארוך יותר.
הנפשה של מאפייני צבע
Paint הוא התהליך שבו קובעים את הסדר שבו צריך לצייר את האלמנטים במסך. בדרך כלל זו המשימה שנמשכת הכי הרבה זמן מכל המשימות בצינור עיבוד הנתונים.
רוב התהליך של יצירת התמונה בדפדפנים מודרניים מתבצע באמצעות מעבדי רסטר בתוכנה. בהתאם לאופן שבו הרכיבים באפליקציה מקובצים בשכבות, יכול להיות שיהיה צורך לצייר גם רכיבים אחרים מלבד הרכיב שהשתנה.
אנימציה של מאפיינים מורכבים
הרכבה היא התהליך של הפרדת הדף לשכבות, המרת המידע על המראה של הדף לפסיקלים (רסטורציה) והרכבת השכבות יחד כדי ליצור דף (הרכבה).
לכן, המאפיין opacity
נכלל ברשימה של דברים שקל ליצור להם אנימציה.
כל עוד הנכס הזה נמצא בשכבה משלו, אפשר לטפל בשינויים בו על ידי ה-GPU בשלב הרכבת התמונות.
דפדפנים מבוססי Chromium ו-WebKit יוצרים שכבה חדשה לכל רכיב שיש לו מעבר או אנימציה ב-CSS ב-opacity
.
מהי שכבה?
כשמניחים את הפריטים שרוצים להוסיף להם אנימציה או להעביר אותם לשכבה חדשה, הדפדפן צריך רק לצייר מחדש את הפריטים האלה ולא את כל השאר. יכול להיות שאתם מכירים את הרעיון של שכבה ב-Photoshop שמכילה כמה אלמנטים שאפשר להזיז יחד. שכבות הרינדור בדפדפן דומות לרעיון הזה.
הדפדפן מצליח לקבל החלטות טובות לגבי האלמנטים שצריכים להופיע בשכבה חדשה, אבל אם הוא מחמיץ אחד מהם, יש דרכים לאלץ את יצירת השכבה. מידע נוסף זמין במאמר איך יוצרים אנימציות עם ביצועים גבוהים. עם זאת, חשוב ליצור שכבות חדשות בזהירות כי כל שכבה משתמשת בזיכרון. במכשירים עם זיכרון מוגבל, יצירת שכבות חדשות עלולה לגרום לבעיה חמורה יותר בביצועים מאשר הבעיה שאתם מנסים לפתור. בנוסף, צריך להעלות את הטקסטורות של כל שכבה ל-GPU. לכן, יכול להיות שתגיעו למגבלות של רוחב הפס בין המעבד לבין המעבד הגרפי.
ביצועים של CSS לעומת JavaScript
יכול להיות שתתהו: מבחינת ביצועים, עדיף להשתמש ב-CSS או ב-JavaScript ליצירת אנימציות?
אנימציות שמבוססות על CSS ואנימציות אינטרנט (בדפדפנים שתומכים ב-API) מטופלות בדרך כלל בשרשור שנקרא שרשור המאגר. זה שונה מהממשק הראשי של הדפדפן, שבו מתבצעים עיצוב, פריסה, ציור ו-JavaScript. כלומר, אם הדפדפן מפעיל משימות יקרות בשרשור הראשי, האנימציות האלה יכולות להמשיך לפעול בלי הפרעה.
כפי שמוסבר במאמר הזה, במקרים רבים גם שינויים אחרים בטרנספורמציות ובאופקטים של האטימות יכולים להיות מטופלים על ידי חוט המאגר.
אם אנימציה כלשהי מפעילה ציור, פריסה או את שניהם, ה-thread הראשי יצטרך לבצע עבודה. זה נכון גם לגבי אנימציות CSS וגם לגבי אנימציות JavaScript, וסביר להניח שהעלות הנלוות של הפריסה או הצביעה תהיה זניחה בהשוואה לכל עבודה שקשורה להרצה של CSS או JavaScript, כך שהשאלה הזו לא רלוונטית.