תוספים ל-Chrome: הרחבת ממשק ה-API לתמיכה בניווט מיידי

Dave Tapuska
Dave Tapuska

אמ;לק: ה-API של התוספים עודכן כדי לתמוך במטמון לדף הקודם/הבא, טעינה מראש של ניווטים. פרטים נוספים מופיעים בהמשך.

ב-Chrome השקיעו מאמצים רבים כדי להאיץ את הניווט. ניווט מיידי טכנולוגיות כמו מטמון לדף הקודם/הבא (נשלח במחשב דרך Chrome 96) וכללי ספקולציות (נשלח ב-Chrome 103) משפרות גם את החזרה וגם את ההתקדמות חוויה אישית. בפוסט הזה נבחן את העדכונים שביצענו בדפדפן ממשקי API של תוספים כדי להתאים לתהליכי העבודה החדשים האלה.

הבנת סוגי הדפים

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

הוצאה של הדף הפעיל
הסרת הדף הפעיל.

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

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

סוגי דפים
סוגי דפים.

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

מה משתנה אצל מפתחי תוספים?

FrameId == 0

ב-Chromium, אנחנו מתייחסים למסגרת העליונה/הראשית בתור המסגרת החיצונית ביותר.

מחברי תוספים שמתבססים על frameId מהמסגרת החיצונית ביותר הוא 0 (שיטה מומלצת קודמת) עלולות להיות בעיות. לכרטיסייה יכולות להיות עכשיו כמה פריימים קיצוניים (בעיבוד מראש ובמטמון) והשערה שיש מודל מסגרת שגויה של כרטיסייה. frameId == 0 עדיין ימשיך לייצג את המסגרת החיצונית של הדף הפעיל, אבל את הפריימים הכי חיצוניים דפים אחרים באותה כרטיסייה לא יהיו אפס. ל-frameType יש שדה חדש נוסף כדי לתקן את הבעיה. עיינו בקטע איך קובעים אם מסגרת היא המסגרת החיצונית ביותר? בפוסט הזה.

מחזור החיים של מסגרות לעומת מסמכים

מושג נוסף שבעייתי בשימוש בתוספים הוא מחזור החיים של מסגרת. מסגרת מארחת מסמך (שמשויך לכתובת URL שהתחייבת אליה). המסמך יכול להשתנות (למשל באמצעות ניווט), אבל ה-frameId לא ישתנה. לכן, קשה לשייך שמשהו קרה במסמך מסוים עם רק frameIds. אנחנו משיקים קונספט של documentId שהוא מזהה ייחודי של כל מסמך. אם מנווטים במסגרת פותח מסמך חדש שהמזהה ישתנה. השדה הזה שימושי עבור קביעת המועד שבו דפים משנים את מצב מחזור החיים שלהם (בין עיבוד מראש/פעיל/שמור במטמון) כי הוא נשאר ללא שינוי.

אירועי ניווט באתר

אירועים במרחב השמות chrome.webNavigation יכול לפעול מספר פעמים בהתאם למחזור החיים שבו הוא נמצא. צפייה "איך אפשר לדעת באיזה מחזור חיים נמצא הדף?" בקטעים איך קובעים מתי דף עובר?

איך אפשר לדעת מהו מחזור החיים של הדף?

DocumentLifecycle נוסף למספר ממשקי API של תוספים שבהם הframeId היה שהיו זמינים בעבר. אם הסוג DocumentLifecycle קיים באירוע (למשל onCommitted), הערך שלו הוא המצב שבו האירוע נוצר. תמיד אפשר לשלוח שאילתות מידע מ-WebNavigation getFrame() ו-getAllFrames() אבל עדיף להשתמש בערך מהאירוע. אם אתה משתמש בכל אחת מהשיטות יש לשים לב שמצב המסגרת עשוי להשתנות בין מועד האירוע נוצר וכשההבטחות חוזרות בשתי השיטות נפתרו.

DocumentLifecycle מכיל את הערכים הבאים:

  • "prerender אינץ' : לא מוצג כרגע למשתמש, אבל מתכונן לקראת הצגה למשתמש.
  • "active": מוצג כרגע למשתמש.
  • "cached": מאוחסן במטמון לדף הקודם/הבא.
  • "pending_deletion": מתבצעת השמדה של המסמך.

איך אפשר לבדוק אם מסגרת היא המסגרת החיצונית ביותר?

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

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

  • "outermost_frame": נקרא בדרך כלל המסגרת העליונה. שימו לב יש כמה שפות כאלה. לדוגמה, אם יש קובץ שעבר עיבוד מראש וקובץ שנשמר במטמון לכל דף יש מסגרת חיצונית ביותר, שאפשר לקרוא למסגרת העליונה שלו.
  • "fenced_frame": שמור לשימוש בעתיד.
  • "sub_frame": בדרך כלל iframe.

אנחנו יכולים לשלב את DocumentLifecycle עם FrameType ולקבוע אם פריים של המסגרת החיצונית הפעילה. מוצרים לדוגמה: tab.documentLifecycle === “active” && frameType === “outermost_frame”

איך אפשר לפתור בעיות בנושא זמן שימוש במסגרות?

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

כדי לטפל בבעיה, הוספנו את documentId (ו-parentDocumentId). הפונקציה webNavigation.getFrame() השיטה הזו הופכת את frameId לאופציונלי אם צוין documentId. הערך documentId ישתנה בכל פעם שמנווטים במסגרת.

איך אוכל לקבוע מתי דף עובר?

יש אותות מפורשים כדי לקבוע מתי דף עובר בין מדינות.

בואו נבחן את האירועים של WebNavigation.

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

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

אפשר לראות את זה בתרשים הבא, שבו רואים את השינוי של documentId ל-"xyz" כשהדף שעבר עיבוד מראש הופך לדף הפעיל.

ה-documentId משתנה כשהדף שעבר עיבוד מראש הופך לדף הפעיל
הdocumentId משתנה כשהדף שעבר עיבוד מראש הופך דף פעיל.

כשדף עובר ממטמון לדף הקודם/הבא או מעיבוד מראש אל יהיו שלושה אירועים נוספים (אבל עם DocumentLifecyle) "active").

onBeforeNavigate
onCommitted
onCompleted

האירוע documentId יישאר ללא שינוי באירועים המקוריים. הדבר שמוצג למעלה כאשר documentId == xyz מופעל. שימו לב אותם אירועי ניווט, מלבד onDOMContentLoaded אירוע כי הדף כבר נטען.

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