HTML5: מבוא ל- HTML5 Web Workers ותכנות מקבילי ב- JavaScript

7 באוגוסט 2011

tags: , , , ,
3 comments

JavaScript Threads Web Workers HTML5פיתוח ב- JavaScript, בהשוואה לסביבות פיתוח אחרות, סבל עד לאחרונה ממגבלה קשה: ביצוע של קוד ה- JavaScript היה מוגבל ל- Thread בודד בדפדפן.
לאור העובדה שמשתמשים דורשים כיום אפליקציות עשירות עם חווית משתמש טובה, וכן רוב המחשבים כוללים יותר ממעבד אחד – נדרשת כיום גישה שונה לפיתוח אפליקציות ב- JavaScript, העושה שימוש ביותר מ- Thead בודד.

לפני עידן ה- HTML5 Web Workers

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

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

JavaScript Threads Web Workers HTML5

ודוגמא נוספת מפיירפוקס 5:

JavaScript Threads Web Workers HTML5

מפתחים התמודדו עם נושא ביצוע פעולות אסינכרוניות ב- JavaScript במספר דרכים, ביניהן שימוש בפונקציות כמו ()setTimeout ו- ()setInterval, ביצוע קריאות HTTP בצורה אסינכרונית ע”י XMLHttpRequest וכו’, אך עדיין – הבעיה שסקריפט רץ על אותו Thread שבו משתמש הדפדפן כדי לצייר את האלמנטים ולהגיב לפעולות המשתמש לא נפתרה.

הכירו את Web Workers

Web Workers API, ספסיפיקציית JavaScript חדשה ב- HTML5 מאפשרת להריץ סקריפט ברקע, וע”י כך לבצע משימות מבלי להפריע ל- Thread שבו משתמש הדפדפן לציור האלמנטים ותגובה לקלט מהמשתמש.

חשוב לדעת! לא כל קטע קוד JavaScript יכול לרוץ ב- Web Workers.

יצירת ה- Web Workers הראשון שלי

בדוגמא הנוכחית ניצור דף HTML המפעיל Web Worker המבצע עבודה ברקע. במקרה שלנו, הדף הראשי ישלח ל- Worker מחרוזת, ה- Worker יבצע ברקע עיבוד כלשהו על המחרוזת ויחזיר אותה לדף הראשי. הדף הראשי יציג את התוצאה באלמנט ע”ג הדף.

1. קוד ה- JavaScript של WebWorker צריך להיות פיזית בקובץ נפרד. לכן ניצור קובץ JavaScript חדש, לדוגמא בשם helloworkers.js.

2. כדי לעבוד עם ה- Web Worker עלינו ליצור בתוך קוד JavaScript אובייקט חדש מסוג Worker ולהעביר אליו את שם הקובץ שבו נמצא הקוד שירוץ ברקע.

<script>
  var worker = new Worker('helloworkers.js');
</script
>

3. ניתן ל- Worker סימן שהוא יכול להתחיל את ריצתו. הדפדפן יצור Thread חדש ויריץ את הסקריפט.

<script>
  var worker = new Worker('helloworkers.js'
);

  worker.postMessage();

</script
>

4. התקשורת בין ה- Thread הראשי לבין ה- Worker היא באמצעות הודעות (messages) שיכולות להיות מחרוזות רגילות או אובייקטים ב- JSON. כדי להאזין להודעות המתקבלות מה- Worker, נירשום פונקציה לטיפול באירוע message.

<script>
  var worker = new Worker('helloworkers.js'
);

  worker.addEventListener(
"message", function
(event) {

   
// Do something with the message sent by the worker

  },
false
);

  worker.postMessage(
"guy");
</script
>

5. הפונקציה הזאת מקבלת אובייקט מסוג MessageEvent שמכיל את תוכן הודעה בשדה data. נוציא את הערך מתוך השדה data ונכתוב אותו לתוך אלמנט כלשהו ב- DOM.

<script>
  var worker = new Worker('helloworkers.js'
);

  worker.addEventListener(
"message", function
(event) {

   
// Create a new element that will show the message content
    // sent from the worker
    var span = document.createElement("span"
);
    span.innerHTML = event.data;
    document.body.insertBefore(span);

  },
false
);

  worker.postMessage(
"guy");
</script
>

6. כעת נממש את ה- Worker עצמו בקובץ helloworkers.js. כזכור, התוכנית הראשית יוצרת את ה- Worker ומעבירה לו את ההודעה הראשונה ע”י שימוש בפונקציה postMessage, שגורמת לו להתחיל לפעול.

לכן, השורה הראשונה שלנו בקובץ helloworkers.js תהיה רישום של פונקציה לטיפול באירוע message של הדף כדי שנהיה מסוגלים לקבל ממנו קלט ולרוץ בהתאם.

// helloworkers.js

// Defining the callback function raised when the main page will call us
this.addEventListener('message', messageHandler, false);

7. כעת נממש את הפונקציה messageHandler שבה למעשה יושב המימוש של ה- Worker. במימוש לדוגמא שאני מביא כאן, אנחנו מקבלים מחרוזת מהתוכנית הראשית, ומוסיפים לה את המילה Hello. את התשובה, אנחנו מחזירים לדף הראשי ע”י שליחת הודעה עם המחרוזת הסופית.

// helloworkers.js

// Defining the callback function raised when the main page will call us
this.addEventListener('message', messageHandler, false
);

function
messageHandler(event) {

 
// Accessing to the message data sent by the main page
  var
messageSent = event.data;

 
// Preparing the message that we will send back
  var messageReturned = "Hello "
+ messageSent;

 
// Posting back the message to the main page
  this.postMessage(messageReturned);
}

8. סיום פעולת ה- Worker. חשוב לדעת שה- Worker ירוץ וישאר בזיכרון עד שנפסיק את פעולתו. יש 2 דרכים להפסיק פעולת Worker:

  • מתוך העמוד הראשי, ע”י קריאה לפונקציה ()terminate באופן הבא:
// Terminate the worker
worker.terminate();
  • מתוך ה- Worker עצמו ע”י שימוש בפונקציה ()close:
// End this worker's work and free memory 
this.close();

נסו את ה- Web Workers API עם אינטרנט אקספלורר 10

JavaScript Threads Web Workers HTML5גירסת המפתחים השניה של אינטרנט אקספלורר 10, ששוחררה לא מזמן, מכילה תמיכה ב- Web Workers.

עם אינטרנט אקספלורר 10 אפשר לראות את הדוגמא הסופית שהצגתי בפוסט בכתובת: http://html5demos.apphb.com/HTML5/WebWorkers/WebWorkersDemo.html

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

בפוסט הבא על Web Workers אציג כיצד ניתן להעביר הודעות מורכבות יותר בפורמט Json בין ה- Worker לדף הראשי.

תהנו!

Add comment
facebook linkedin twitter email

3 comments

  1. BnayaA7 באוגוסט 2011 ב 20:54

    פוסט נהדר , מחכה לפוסט הבא!

  2. Rotem Bloom9 באוגוסט 2011 ב 8:29

    אחלה של פוסט תודה.
    האם זה כבר סטנדרט לכול הדפדפנים התומכים ב-HTML5?

  3. גיא בורשטיין9 באוגוסט 2011 ב 8:39

    @רותם – למיטב ידיעתי רק אקספלורר 10 וכרום תומכים בזה. אבל זה שווה בדיקה נוספת.

Comments are closed.