שיפור ביצועי Frontend וגלילה באתרים

על ביצועי Frontend באתרים בדגש על שיפור ביצועי גלילה.

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

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

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

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

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

על ביצועי Frontend ופעולת ה Repainting בדפדפנים

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

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

אם נעזר בתמונות שגוגל סיפקו לנו, העבודה שהדפדפן מבצע (אותו צינור עליו אנו מדברים) מתבצע בצורה הבאה:

triggering layout and paint

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

frame-no-layout

שימוש ב Chrome Dev Tools לזיהוי צוואר הבקבוק של פעולת ה Repainting

ניתן להשתמש בכלי המפתחים של כרום (Chrome Developer Tools) על מנת לזהות במהירות איזורים שנצבעים באתר שלכם מחדש. גשו לכלי המפתחים ולחצו על Esc במקלדת, לאחר מכן גשו ללשונית Rendering ובחרו את האפשרות "Show paint rectangles" כבתמונה הבאה:

paint-flashing-chrome-dev-tools

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

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

 

שימו לב למספר דברים שרואים בוידאו במהלך הגלילה:

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

כל החלקים הללו נצבעים מחדש ומעמיסים על הדפדפן בכל פעם שמשתמש מבצע גלילה באתר. יש לכם רעיון מה משותף לשלושתם? אני מניח שניחשתם… לכולם התכונה position:fixed.

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

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

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

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

יצירת שכבות (layers) חדשות עבור אותם אלמנטים

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

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

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

Layer Promotion

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

התכונה WILL-CHANGE

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

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

.moving-element {
  will-change: transform;
}

אגב, אם אתם מעוניינים בתמיכה בדפדפנים ישנים יותר – תוכלו להשתמש בסוג של hack שקיים כבר שנים והוא שימוש ב translateZ כבדוגמה הבאה:

.moving-element {
  transform: translateZ(0);
}

אך שימו לב למספר נקודות בהקשר לתכונה will-change לפני שאתם רצים להשתמש בה:

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

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

 

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

כיצד להוסיף את התכונה will-change באמצעות Javascript?

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

var el = document.getElementById('element');

// Set will-change when the element is hovered
el.addEventListener('mouseenter', hintBrowser);
el.addEventListener('animationEnd', removeHint);

function hintBrowser() {
  // The optimizable properties that are going to change
  // in the animation's keyframes block
  this.style.willChange = 'transform, opacity';
}

function removeHint() {
  this.style.willChange = 'auto';
}

מספר טיפים לביצועי Fronend טובים יותר

ישנם מספר דברים שבאפשרותכם לעשות בכדי לשפר את ביצועי הגלילה והאנימציות באתר שלכם. כתוצאה משינויים אלו, ה CPU/GPU לא ייאלץ לעבוד כ״כ קשה וזה אף יתורגם לגולשים מרוצים יותר וצריכת סוללה נמוכה יותר במכשירי מובייל. בוא ניתן מספר טיפים:

  • המנעו משימוש בתמונות רקע להם התכונה background-attachment:fixed. בדפדפנים מסויימים אלו יגרמו לצביעה מחדש במהלך גלילה ולביצועים ירודים.
  • אם אתם משתמשים בסליידרים או אנימציות באתר שלכם, וודאו אתם יוצרים עבורם שכבה נפרדת באמצעות התכונה will:change.
  • אם ישנם אפקטים רבים של CSS3, לדוגמה – הרבה פינות מעוגלות (rounded corners), תכונות כמו linear-gradients למינהן והצללות (shadows), שיקלו להסיר אותן או להפחית את השימוש בהן. אין בעיה להשתמש באלו אך זכרו שבמידה וקיימים במידה מופרזת באתר שלכם – תהיה לכך השפעה על ביצועי ה Frontend.
  • תמיד תמיד השתמשו בגודל התמונה המדוייק שעל הדפדפן להציג ותחסכו ממנו לשנות בעצמו את גודל התמונה על המסך. אם אתם עובדים עם וורדפרס, תנו מבט במדריך שכתבתי המסביר על יצירת גדלים של תמונות באתרים אלו.
  • אמנם לא נגענו בחלק זה, אך במידה ואתם משתמשים באנימציות – נסו להשתמש ב requestAnimationFrame. שימוש במטודה זו יכול לשפר את ביצועי האנימציות ואת ה FPS בצורה דרסטית.

לסיכום

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

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

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

רועי יוסף
רועי יוסף

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

{ 1 תגובה… הוסף אחת }

השאירו תגובה

פעימות
Up!
wordpress-estimated-reading-time
הצגת משך זמן הקריאה המוערך של פוסט באתרי וורדפרס

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