סקירה כללית של worker באינטרנט

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

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

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

כשמדובר ב-JavaScript, בדרך כלל אפשר לבצע עבודה על ה-thread הראשי, אבל רק כברירת מחדל. אפשר לרשום שרשורים נוספים ב-JavaScript ולהשתמש בהם. התכונה שמאפשרת לבצע ריבוי שרשורים ב-JavaScript נקראת Web Workers API.

השימוש ב-Web worker שימושי כשיש עבודה יקרה מבחינה חישובית שפשוט אי אפשר להריץ ב-thread הראשי, בלי לגרום למשימות ארוכות שבגללן הדף לא מגיב. משימות כאלה בהחלט יכולות להשפיע על האינטראקציה עם הצבע הבא (INP) באתר, כך שרצוי לדעת מתי יש עבודה שאפשר לבצע לגמרי מה-thread הראשי. כך אפשר לפנות יותר מקום למשימות אחרות ב-thread הראשי, כדי שהאינטראקציות של המשתמשים יהיו מהירות יותר.

המודול הזה וההדגמה הבאה מציגה תרחיש לדוגמה קונקרטי מתייחס לעובדי אינטרנט. ההדגמה עצמה מראה איך משתמשים ב-Web worker כדי לקרוא מטא-נתונים של תמונות מקובץ JPEG מה-thread הראשי, ואיך אפשר להחזיר את המטא-נתונים ל-thread הראשי כדי שהמשתמש יוכל לראות אותם.

איך השקנו את Web worker

רישום עובד אינטרנט באמצעות יצירת מופע של המחלקה Worker. במקרה כזה, צריך לציין איפה נמצא קוד ה-Web worker, שהדפדפן טוען עבורו ויוצר לו שרשור חדש. ה-thread שמתקבל נקרא בדרך כלל שרשור worker.

const myWebWorker = new Worker('/js/my-web-worker.js');

בקובץ ה-JavaScript של העובד – my-web-worker.js במקרה הזה – אפשר לכתוב קוד, שלאחר מכן ירוץ בשרשור נפרד של worker.

מגבלות של Web worker

בשונה מ-JavaScript שפועל על ה-thread הראשי, לעובדי אינטרנט אין גישה ישירה להקשר של window, והגישה שלהם לממשקי ה-API שהיא מספקת מוגבלת. עובדי האינטרנט כפופים לאילוצים הבאים:

  • עובדי אינטרנט לא יכולים לגשת ישירות ל-DOM.
  • עובדי אינטרנט יכולים לתקשר עם ההקשר window באמצעות צינור עיבוד נתונים להעברת הודעות. כלומר, עובד אינטרנט יכול לגשת באופן עקיף ל-DOM.
  • ההיקף של קובץ האינטרנט הוא self ולא window.
  • להיקף של worker באינטרנט יש גישה לפרימיטיבים ולמבנים של JavaScript, וגם לממשקי API כמו fetch ומספר די גדול של ממשקי API אחרים.

איך עובדי אינטרנט מדברים עם window

העובד באינטרנט יכול לתקשר עם ההקשר window של ה-thread הראשי באמצעות צינור עיבוד נתונים. צינור עיבוד הנתונים מאפשר להעביר נתונים ל-thread הראשי ולעובד האינטרנט, וממנו. כדי לשלוח נתונים מעובד אינטרנט ל-thread הראשי, צריך להגדיר אירוע message בהקשר של עובד האינטרנט (self)

// my-web-worker.js
self.addEventListener("message", () => {
  // Sends a message of "Hellow, window!" from the web worker:
  self.postMessage("Hello, window!");
});

לאחר מכן, בסקריפט בהקשר של window ב-thread הראשי, תוכלו לקבל את ההודעה מה-thread של ה-Web worker באמצעות אירוע message נוסף:

// scripts.js

// Creates the web worker:
const myWebWorker = new Worker('/js/my-web-worker.js');

// Adds an event listener on the web worker instance that listens for messages:
myWebWorker.addEventListener("message", ({ data }) => {
  // Echoes "Hello, window!" to the console from the worker.
  console.log(data);
});

צינור העברת ההודעות של עובד האינטרנט הוא דרך מילוט מהקשר של עובד האינטרנט. באמצעותו תוכלו לשלוח נתונים ל-window מ-Web worker, שאפשר להשתמש בו כדי לעדכן את ה-DOM או לבצע פעולות אחרות שחייבים לבצע ב-thread הראשי.

בוחנים את הידע

באיזה שרשור פועל Web Worker?

ה-thread הראשי.
אפשר לנסות שוב.
שרשור משלו (שנקרא גם שרשור של עובד אינטרנט).
נכון!
ה-thread של ה-GPU.
אפשר לנסות שוב.

מה יש לעובד אינטרנט גישה?

פרימיטיבים של JavaScript, כמו מערכים ואובייקטים.
נכון!
קבוצת משנה מחמירה של ממשקי API שזמינים בהקשר של window, כולל fetch.
נכון!
ההקשר window, אבל רק באופן עקיף.
נכון!

איך עובד אינטרנט יכול לגשת להקשר של 'window'?

ישירות, הפניה לחברים באובייקט window.
אפשר לנסות שוב.
עובד אינטרנט לא יכול לגשת ל-window בשום אופן.
אפשר לנסות שוב.
באמצעות צינור להעברת הודעות שמופעל על ידי השיטה postMessage בהקשר של Web Worker (self).
נכון!

השלב הבא: תרחיש לדוגמה של עובד אינטרנט

במודול הבא מוצג תרחיש לדוגמה לשימוש ב-Web worker של בטון. במודול הזה, ה-Web Worker משמש לאחזור קובץ JPEG מכתובת URL נתונה וקריאת המטא-נתונים של תצוגת Exif ב-Web worker. אחר כך הנתונים האלה נשלחים בחזרה ל-thread הראשי כדי שיוצגו למשתמש.