מבט מבפנים על דפדפן אינטרנט מודרני (חלק 2)

Mariko Kosaka

מה קורה בניווט

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

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

הוא מתחיל בתהליך בדפדפן

תהליכי דפדפן
איור 1: ממשק המשתמש של הדפדפן בחלק העליון, תרשים של תהליך הדפדפן עם ממשק משתמש, רשת ואחסון השרשור בתוך למטה

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

ניווט פשוט

שלב 1: טיפול בקלט

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

טיפול בקלט של משתמשים
איור 1: שרשור בממשק המשתמש ששואל אם הקלט הוא שאילתת חיפוש או כתובת URL

שלב 2: מתחילים בניווט

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

התחלת ניווט
איור 2: ה-thread של ממשק המשתמש שמדבר אל השרשור ברשת כדי לנווט אל mysite.com

בשלב הזה, שרשור הרשת עשוי לקבל כותרת הפניה אוטומטית של השרת, כמו HTTP 301. במקרה הזה, ה-thread של הרשת מתקשר עם ה-thread של ממשק המשתמש שהשרת מבקש הפניה אוטומטית. לאחר מכן: תישלח בקשה נוספת לכתובת URL.

שלב 3: קריאת התשובה

תגובת HTTP
איור 3: כותרת תגובה שמכילה את סוג התוכן ואת המטען הייעודי (payload) שמכיל את הנתונים בפועל.

אחרי שגוף התשובה (המטען הייעודי (Payload) מתחיל להגיע, ה-thread של הרשת בודק את הבייטים הראשונים של הסטרימינג, אם יש צורך. כותרת Content-Type של התגובה צריכה לציין מהו סוג הנתונים, אבל מכיוון שהוא עשוי להיות חסר או שגוי, לכידת סוגי MIME מתבצעת כאן. "עסק בעייתי" כפי שמצוין בקוד המקור. תוכלו לקרוא את התגובה כדי לראות איך דפדפנים שונים מטפלים בצמדים של סוג תוכן/מטען ייעודי (payload).

אם התגובה היא קובץ HTML, השלב הבא יהיה העברת הנתונים למעבד אבל אם מדובר בקובץ ZIP או בקובץ אחר, המשמעות היא שזו בקשת הורדה הוא צריך להעביר את הנתונים למנהל ההורדות.

לכידת סוג MIME
איור 4: שרשור ברשת שבו השאלה אם נתוני התגובות הם HTML מאתר בטוח

כאן מתבצעת גם בדיקת SafeBrowsing. אם נראה שהדומיין ונתוני התגובה תואמים לאתר זדוני ידוע, סימן שה-thread של הרשת כדי להציג דף אזהרה. בנוסף, Cross Origin RBlocking (CORB) מתבצעת בדיקה כדי לוודא שכתובות אתרים רגישות לא מגיעים לתהליך של רינדור.

שלב 4: מוצאים תהליך של רינדור

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

חיפוש תהליך של רינדור
איור 5: שרשור ברשת שאומר לשרשור בממשק המשתמש כדי למצוא תהליך של כלי רינדור

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

שלב 5: שמירת הניווט

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

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

שמירת הניווט
איור 6: כתובת IPC בין הדפדפן לתהליכי הרינדור, בבקשה לעבד את הדף

שלב נוסף: הטעינה הראשונית הושלמה

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

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

סיום הטעינה של הדף בטעינה
איור 7: פרוטוקול IPC מהכלי לרינדור ועד לתהליך הדפדפן כדי להודיע שהדף 'נטענו'

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

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

הגורם המטפל באירוע beforeunload
איור 8: פרוטוקול IPC מתהליך הדפדפן ועד לתהליך רינדור, שמדווח שהוא עומד מעבר לאתר אחר

אם הניווט התחיל מתהליך הרינדור (למשל, משתמש לחץ על קישור או JavaScript בצד הלקוח הריץ window.location = "https://newsite.com") את תהליך הרינדור בודק קודם את beforeunload handlers. לאחר מכן, הוא עובר את אותו תהליך כמו תהליך בדפדפן הופעל ניווט. ההבדל היחיד הוא שבקשת הניווט החלה תהליך רינדור לתהליך הדפדפן.

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

ניווט חדש והסרת טעינה
איור 9: שתי כתובות IPC מתהליך הדפדפן לתהליך רינדור חדש שאומרים לעבד את הדף ולבקש מהכלי לרינדור הישן להסיר את הנתונים שנטענו

במקרה של Service Worker

אחד מהשינויים האחרונים בתהליך ניווט זה הוא service worker. קובץ שירות (service worker) הוא שיטה לכתוב שרת proxy של רשת בקוד האפליקציה; ומאפשרת למפתחי אתרים לקבל יותר שליטה על לשמור במטמון באופן מקומי ומתי לקבל נתונים חדשים מהרשת. אם Service Worker מוגדר לטעון את הדף מהמטמון, אין צורך לבקש את הנתונים מהרשת.

מה שחשוב לזכור הוא ש-Service Worker הוא קוד JavaScript שרץ בכלי רינדור תהליך האימות. אבל כשבקשת הניווט מתקבלת, איך תהליך הדפדפן יודע שיש לאתר קובץ שירות (service worker)?

חיפוש היקף של Service Worker
איור 10: שרשור הרשת בתהליך הדפדפן חיפוש היקף של קובץ שירות (service worker)

כש-Service Worker רשום, ההיקף של Service Worker נשמר כחומר עזר (ניתן לקרוא מידע נוסף על היקף ב המאמר בנושא מחזור החיים של Service Worker). במהלך ניווט, שרשור הרשת בודק את הדומיין מול קובץ שירות רשום שלו, אם קובץ שירות (service worker) רשום בכתובת ה-URL הזו, ה-thread של ה-UI ימצא תהליך של רינדור כדי להריץ את הקוד של Service Worker. Service Worker עשוי לטעון נתונים מהמטמון, וכך לבטל את השימוש את הצורך לבקש נתונים מהרשת, או לבקש משאבים חדשים מהרשת.

ניווט Workworker
איור 11: שרשור ממשק המשתמש בתהליך הדפדפן, שמתחיל תהליך של רינדור לטיפול בשירות worker; שרשור עובד בתהליך רינדור, ולאחר מכן מבקש נתונים מהרשת

אפשר לראות את המעבר הלוך ושוב בין תהליך הדפדפן לתהליך הרינדור עלול לגרום לעיכובים אם קובץ שירות (service worker) מחליט בסופו של דבר לבקש נתונים מהרשת. הטעינה מראש של הניווט היא מנגנון להאצה לטעון משאבים במקביל להפעלה של Service Worker. היא מסמנת את הבקשות האלה בכותרת, וכך השרתים יכולים להחליט לשלוח תוכן שונה הבקשות האלה; לדוגמה, הצגת נתונים מעודכנים במקום מסמך שלם.

טעינה מראש של הניווט
איור 12: שרשור ממשק המשתמש בתהליך הדפדפן, שמתחיל תהליך של רינדור לטיפול בשירות עובד בזמן ביצוע בקשת רשת במקביל

סיכום

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

נהנית מהפוסט? אם יש לך שאלות או הצעות לגבי פוסט עתידי, אשמח נשמח לשמוע מכם בקטע התגובות בהמשך או ב-@kosamari ב-Twitter.

השלב הבא: הפעולות הפנימיות של תהליך כלי הרינדור