אמ;לק: השתמשו שוב ברכיבי ה-DOM והסירו את אלה שרחוקים אזור התצוגה. כדאי להשתמש ב-placeholders כדי להביא בחשבון נתונים באיחור. הנה את ההדגמה ואת הקוד של באמצעות גלילה.
מודעות גלילה אינסופיות מופיעות בכל רחבי האינטרנט. רשימת האומנים ב-Google Music הראשון, ציר הזמן של Facebook הוא אחד, וגם הפיד של טוויטר בשידור חי הוא אחד מהם. שלך גוללים למטה ולפני שמגיעים לתחתית המסך, מופיע קסם של תוכן חדש לכאורה. זו חוויה חלקה למשתמשים, וקל אפשר לראות את הערעור.
עם זאת, האתגר הטכני שעומד מאחורי גלילה אינסופית קשה יותר ממנו נראה. טווח הבעיות שבהן אתם נתקלים כשרוצים לבצע את הפעולה הנכונהTM הוא עצום. הוא מתחיל בדברים פשוטים, כמו הקישורים בכותרת התחתונה כמעט בלתי ניתן להגעה, כי התוכן כל הזמן דוחף את הכותרת התחתונה. אבל שיהיו קשות יותר. איך מטפלים באירוע של שינוי גודל כשמישהו מסובב את את הטלפון לאורך או לרוחב או איך מונעים מהטלפון להתחרט הפסקתם לכאוב כשהרשימה נמשכת יותר מדי?
הדבר הנכוןTM
חשבנו שזו סיבה מספקת כדי לחשוב על יישום של קובצי עזר שמראה דרך להתמודד עם כל הבעיות האלו בדרך לשימוש חוזר, שמירה על סטנדרטים של ביצועים.
נשתמש ב-3 טכניקות כדי להשיג את המטרה שלנו: מיחזור DOM, מצבות ועוגן גלילה.
מקרה ההדגמה שלנו יהיה חלון צ'אט דמוי Hangouts שבו נוכל לגלול דרך ההודעות. הדבר הראשון שאנחנו זקוקים לו הוא מקור אינסופי של צ'אט הודעות. מבחינה טכנית, אף אחד מגוללים האינסופיים בחוץ באמת אינסופי, אבל עם כמות הנתונים שזמינים שאפשר לאמץ שיש להן גלילה מהירה. כדי לפשט את הפשטות, פשוט נוסיף קוד בתוך הקוד, קבוצת הודעות צ'אט ולבחור הודעה, מחבר ומצורף תמונה מדי פעם ב- עם כמה נגיעות של עיכוב מלאכותי שיתנהג מעט יותר כמו רשת אמיתית.
מיחזור DOM
מיחזור DOM היא שיטה שלא משתמשים בה כדי לשמור על מספר נמוך של צומתי DOM. באופן כללי, הוא להשתמש ברכיבי DOM שכבר נוצרו מחוץ למסך ביצירת ביקורות חדשות. אומנם צומתי DOM עצמם הם זולים, אבל בחינם, מכיוון שכל אחת מהן מוסיפה עלות נוספת בזיכרון, בפריסה, בסגנון ובצבע. מכשירים מתקדמים יצטמצמו באופן משמעותי אם לא ניתן יהיה להשתמש בהם לגמרי, האתר מכיל DOM גדול מדי לניהול. כמו כן, חשוב לזכור שכל העברה ויישום מחדש של הסגנונות שלך – תהליך שמופעל בכל פעם שכיתה נוסף או הוסר מצומת – גדל יקר יותר עם DOM גדול יותר. מיחזור של צומתי ה-DOM שלך פירושו שנשאיר את המספר הכולל של ה-DOM נמוכים באופן משמעותי, כך שכל התהליכים האלה מהירים יותר.
הקושי הראשון הוא הגלילה עצמה. מכיוון שיש לנו רק חלק זעיר כל הפריטים הזמינים ב-DOM בכל זמן נתון, אנחנו צריכים למצוא דרך אחרת כדי שסרגל הגלילה של הדפדפן ישקף בצורה נכונה את כמות התוכן תיאורטית. נשתמש ברכיב סנטינל של 1 פיקסלים על פיקסל עם טרנספורמציה לאלץ את הרכיב שמכיל את הפריטים - מסלול ההמראה - לקבל גובה. אנחנו נקדם כל אלמנט במסלול לשכבה משלו כדי שהשכבה של המסלול עצמו ריקה לגמרי. אין צבע רקע. שום דבר. אם שכבת המסלול לא ריקה, היא לא כשירה לתצוגה של הדפדפן ונצטרך לאחסן את המרקם בכרטיס הגרפי שלנו בגובה של כמה מאות אלף פיקסלים. בהחלט לא ניתן ליישם מהמכשיר הנייד.
בכל פעם שגוללים, אנחנו בודקים אם אזור התצוגה התקרב מספיק בסוף המסלול. אם כן, נרחיב את המסלול על ידי הזזת הסנטינל ולהעביר את הפריטים שנשארו מאזור התצוגה לתחתית המסך ואכלס אותם בתוכן חדש.
אותו עיקרון חל על גלילה בכיוון ההפוך. עם זאת, אף פעם לא לכווץ את מסלול ההמראה בהטמעה שלנו, כך שהמיקום של סרגל הגלילה יישאר עקביים.
מצבות
כמו שציינו קודם, אנחנו מנסים לגרום למקור הנתונים שלנו להתנהג באופן דומה בעולם האמיתי. עם זמן אחזור של הרשת וכל מה שצריך. המשמעות היא שאם המשתמשים משתמשים בגלילה מהירה, הם יכולים לגלול בקלות מעבר לאלמנט האחרון שיש לנו נתונים עבורם. במקרה כזה, נציב פריט מצבה - placeholder – שיוחלף בפריט בתוכן בפועל ברגע נתונים הגיעו. גם מצבות של מצבות ממוחזרות ויש להן בריכה נפרדת רכיבי DOM לשימוש חוזר. אנחנו צריכים את זה כדי שנוכל לבצע מעבר טוב למצב של פריט מאוכלס בתוכן, שאחרת היה צורם למשתמשים ולמעשה עלולים לגרום להם לאבד את תשומת הלב שלהם להתמקד בו.
אתגר מעניין כאן הוא שפריטים אמיתיים יכולים להיות גבוהים יותר מ פריט המצבה בגלל כמויות שונות של טקסט לכל פריט או תמונה. כדי לפתור את הבעיה, נשנה את מיקום הגלילה הנוכחי בכל פעם נתונים מגיעים ומצבה של מצבה מוחלפת מעל אזור התצוגה, עוגן את מיקום הגלילה לרכיב ולא לערך של פיקסל. הקונספט הזה שנקרא 'עיגון גלילה'.
עיגון גלילה
עיגון הגלילה יופעל גם כשהמצבות יוחלפו וגם כשגודל החלון משתנה (מה שקורה גם כשהמכשירים הפוך!). נצטרך להבין מהו הרכיב הגלוי ביותר שאזור התצוגה הוא. מאחר שניתן לראות את הרכיב הזה רק באופן חלקי, תאחסן את ההיסט מהחלק העליון של הרכיב שבו מתחיל אזור התצוגה.
אם גודל אזור התצוגה ישתנה והמסלול ישתנה, נוכל לשחזר שנראית זהה מבחינה חזותית למשתמש. מנצחים! מלבד שינוי גודל המשמעות של החלון היא שהגובה של כל פריט עשוי להשתנות, אז איך ידוע לך באיזה מרחק צריך למקם את התוכן המעוגן? אנחנו לא! כדי לגלות צריך לפרוס כל אחד מהרכיבים מעל הפריט המקושר ולהוסיף את כל הרכיבים הגובה שלהם, הדבר עלול לגרום להשהיה משמעותית לאחר שינוי הגודל, ואנחנו לא רוצה את זה. במקום זאת, אנחנו מניחים שכל הפריטים שלמעלה הם בגודל זהה כמו מצבה, ומשנים את מיקום הגלילה שלנו בהתאם. כי הרכיבים אנחנו גוללים למסלול, אנחנו משנים את מיקום הגלילה, הפריסה עובדת לפי הצורך בזמן אמת.
פריסה
דילגתי על פרט חשוב: פריסה. כל מיחזור של רכיב DOM בדרך כלל יפרסם את כל המסלול, והוא יפנה אותנו הרבה מתחת יעד של 60 פריימים לשנייה. כדי להימנע מכך, אנחנו נושאים להשתמש באלמנטים שנמצאים במיקום מדויק עם טרנספורמציות. כך אנחנו יכולים להעמיד פנים שכל הרכיבים שנמצאים בהמשך המסלול עדיין תופסים מקום כשבפועל יש רק מקום ריק. מאחר שאנחנו עושים לפריסה של עצמנו, אנחנו יכולים לשמור במטמון את המיקומים שבהם כל פריט מסתיים, טוענת באופן מיידי את הרכיב הנכון מהמטמון כשהמשתמש גולל אחורה.
באופן אידיאלי, פריטים ייצבעו מחדש רק פעם אחת כשהם יצורפו ל-DOM והם לא יאהבו תוספות או הסרות של פריטים אחרים על מסלול ההמראה. כלומר אבל רק בדפדפנים מודרניים.
עריכות מזעזעות
לאחרונה נוספו ל-Chrome תמיכה בהכללת CSS, תכונה שהיא תכונה
שמאפשרת לנו למפתחים לומר לדפדפן שרכיב כלשהו מהווה גבול
ולעבוד יחד. מכיוון שאנחנו עושים כאן את עבודת הפריסה, זה מעולה
בקשה לבידוד. בכל פעם שאנחנו מוסיפים אלמנט למסלול, אנחנו יודעים
הפריטים האחרים לא צריכים להיות מושפעים מההעברה. לכן כל פריט
מקבלים contain: layout
. אנחנו גם לא רוצים להשפיע על שאר האתר שלנו,
אז גם המסלול עצמו צריך לקבל את ההוראה בסגנון הזה.
דבר נוסף שחשבנו עליו הוא השימוש
IntersectionObservers
כמנגנון לזיהוי מקרים שבהם
המשתמש גלל מספיק רחוק כדי שנוכל להתחיל למחזר רכיבים ולטעון
. עם זאת, ל-IntersectionObservers מוגדר זמן אחזור ארוך (כאילו
באמצעות requestIdleCallback
), לכן ייתכן שנרגיש פחות מגיבים עם
IntersectionObservers מאשר בלי. אפילו בהטמעה הנוכחית שלנו באמצעות
אירוע אחד (scroll
) נובע מהבעיה הזו, מאחר שאירועי גלילה נשלחים
על בסיס "המאמץ הטוב ביותר". בסופו של דבר, Houdini’s Compositor Worklet
הוא הפתרון ברמת דיוק גבוהה לבעיה הזו.
עדיין לא מושלם
היישום הנוכחי שלנו של מיחזור DOM אינו אידיאלי מכיוון שהוא יוסיף את כל הרכיבים עוברים דרך אזור התצוגה, במקום להתמקד רק באלה שמופיע במסך. כלומר, כשגוללים באמת מהר, כל כך הרבה עבודה עבור פריסה וציור ב-Chrome שהוא לא יכול לעמוד בקצב. הפעולה תסתיים לא לראות דבר חוץ מהרקע. זה לא סוף העולם, בהחלט יש משהו לשפר.
אנחנו מקווים שתראו עד כמה בעיות פשוטות יכולות להפוך למאתגרות, לשלב חוויית משתמש מעולה עם סטנדרטים גבוהים של ביצועים. ב- Progressive Web Apps הופכות לחוויות ליבה בטלפונים ניידים, חשוב יותר, ומפתחי אתרים יצטרכו להמשיך להשקיע באמצעות דפוסים שעומדים במגבלות הביצועים.
כל הקוד נמצא במאגר שלנו. סיימנו מומלץ לשמור אותו לשימוש חוזר, אבל לא נפרסם אותו כספרייה בפועל npm או כמאגר נפרד. השימוש העיקרי הוא חינוכי.