[ הרצאה · DOTB Meetup #3 · Web Frameworks ]

Revolutionize Web App Performance - Unleash the Power of WebAssembly

וידאו · 1 ביולי 2023 · דניאלה גרין

WebAssembly לא מחליפה JavaScript. דניאלה גרין מראה מתי חישוב כבד בדפדפן חוסך המתנה לרשת, איך מודול WASM נטען, ואיפה המחיר עובר לניהול זיכרון.

צפו בהרצאה
תמונה ממוזערת של ההרצאה: Revolutionize Web App Performance - Unleash the Power of WebAssembly
[ כתבת ההרצאה ]

הסיפור שמאחורי ההרצאה

[ תקציר מהיר ]
  • WebAssembly מאפשרת להריץ בדפדפן קוד שקומפל משפות כמו C, C++ ו-Go. היא משתלבת עם JavaScript, לא באה להחליף אותה.
  • מודול WASM הוא פורמט בינארי קטן וקרוב יותר ל-machine code, ולכן שלבי הפענוח, הקומפילציה וההרצה שלו קצרים יותר לעומת JavaScript דינמית.
  • הביצועים מתאימים במיוחד לעיבוד כבד כמו משחקים, גרפיקה, video editing ו-audio processing - לא לכל interaction רגיל ב-UI.
  • בדמו דניאלה טוענת מודול שקומפל מ-C דרך JavaScript, ממירה את תגובת הרשת ל-array buffer, ניגשת ל-export ומפעילה פונקציית חיבור.
  • ב-Artlist משתמשים בספריית אודיו ב-C שמתקמפלת ל-WASM כדי לעבד סאונד בדפדפן, במקום להפוך פעולה כבדה להמתנה חוזרת לשרת.

WebAssembly לא נועדה להפוך כל אפליקציית React לפרויקט C. היא מעניינת בדיוק במקום שבו JavaScript נדרשת לעשות עבודה שהיא לא נבנתה כדי לעשות בנוחות: עיבוד סאונד, גרפיקה, חישוב כבד, או פעולה שהמשתמש מרגיש בה כל round trip לשרת. בהרצאה הזו דניאלה גרין מפרקת את ההבטחה בלי להעמיד פנים שמדובר בקסם.

הטענה שלה פשוטה: WebAssembly היא עוד שכבה בארגז הכלים של הווב. היא מאפשרת לקחת קוד משפות כמו C, C++ או Go, לקמפל אותו לפורמט בינארי, ולטעון אותו מתוך JavaScript בדפדפן. לא מחליפים את ה-UI ולא זורקים את האקוסיסטם. מזיזים למסלול אחר רק את העבודה שבאמת צריכה אותו.

הבעיה אינה תמיד “הבקאנד איטי”

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

ב-Artlist, דניאלה מתארת את הצורך לעבד סאונד על גבי הווב בלי לפגוע בחוויה. זה לא use case של כפתור ששומר טופס. מדובר בעבודה על אודיו, בפעולות שהולכות ונעשות יקרות יותר כשהקבצים כבדים והאיכות עולה. כאן WebAssembly יכולה להציב את החישוב קרוב למשתמש במקום להפוך אותו לבקשה חוזרת לבקאנד.

אחד הפתרון שמצאנו הוא בעצם WebAssembly.

זה tradeoff, לא הוראה גורפת. מחשוב בלקוח יכול להוריד latency, אבל מעלה דרישות מהמכשיר, מהזיכרון ומהקוד שצריך לתחזק. השאלה הנכונה היא לא “האם WASM מהירה”, אלא איזה שלב במוצר באמת נשבר בגלל החישוב או בגלל הרשת.

מה בעצם רץ בדפדפן

WebAssembly, או WASM, היא פורמט בינארי שהדפדפן יודע להריץ. דניאלה מתארת מסלול של קוד: machine code, assembly, שפות גבוהות יותר כמו C, ואז JavaScript. בניגוד לשפה שמתקמפלת מראש, JavaScript היא שפה דינמית שהמנוע מפרש וממטב בזמן ריצה.

לגמישות הזו יש מחיר. המנוע מבצע parsing, יוצר AST ו-bytecode, מזהה קוד חם, עושה אופטימיזציה ולעיתים צריך לבצע deoptimization כשהטיפוסים או ההנחות משתנים. אלה מנגנונים חכמים, אבל הם עדיין עבודה.

WASM מגיעה כבר בפורמט קומפקטי וקרוב יותר ל-machine code. גם היא צריכה decoding, validation, compilation והרצה, אבל לדברי דניאלה המסלול קצר ורזה יותר. קובץ בינארי קטן יותר יכול לעבור מהר יותר מהשרת, וההרצה יכולה להתאים יותר לעבודה חישובית צפופה.

הפעולות שאני צריכה לעשות עם הקוד כדי להגיע למשין קוד הן הרבה יותר קטנות.

זה לא אומר ש-JavaScript “איטית” או שצריך לקמפל כל helper. JavaScript נשארת הדרך שבה נטענים המודול וה-UI, והיא מעולה לרוב העבודה באפליקציית ווב. WASM היא כלי ממוקד לנתיב שבו ההבדל באמת מורגש.

לא להחליף JavaScript - לחבר אליה מודול

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

בדמו היא מתחילה באפליקציית React פשוטה ובפונקציית add שנכתבה ב-C. כדי לחבר ביניהן, היא מביאה את הקובץ עם fetch, ממירה את ה-response ל-array buffer, ומעבירה אותו ל-WebAssembly.instantiate. מה שחוזר הוא instance עם exports. הפונקציה שהוגדרה כ-exported ב-C זמינה עכשיו ל-JavaScript, ו-React יכולה לשים את התוצאה ב-state ולהציג אותה.

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

זה ממש לא אומר שזאת הרצאה על איך לבוא ולהחליף את JavaScript.

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

אחר כך מגיע המקרה האמיתי יותר. Artlist משתמשת בספריית אודיו שכתובה ב-C, מקמפלת אותה ל-WebAssembly וטוענת אותה דרך JavaScript. דניאלה מדגימה שני קטעי קול במהירויות BPM שונות ואת הפעולה שצריכה לעבד אותם כדי לשנות את הקצב.

אות שמע מיוצג כמערך מספרים. כשהאודיו איכותי יותר והפעולה מורכבת יותר, החישוב הזה דורש משאבים. העברה של הפעולה הזו ל-WASM נותנת לצוות דרך להפעיל ספריית C קיימת בתוך הדפדפן ולשמור את העיבוד קרוב למשתמש. זה אותו עיקרון שפותח שימושים גם למשחקים, 3D ו-video editing: לא כל מוצר צריך אותו, אבל במוצרים הנכונים הוא משנה את גבול האפשרי.

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

מגבלות שאסור להסתיר

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

דניאלה מדברת גם על דיבוג. כלי הדפדפן יכולים להציג ייצוג טקסטואלי של WASM ולא רק בינארי, ואפשר להציב breakpoint. אבל מי שקימפל C צריך עדיין להבין את הפורמט והכלים, לא לצפות לאותה חוויה של DevTools בקוד המקורי.

יש גם עלות ארגונית. צוות frontend שמכניס מודול C או Go מקבל תלות ב-toolchain נוסף, בבדיקות עבור קוד שאינו JavaScript, ובאנשים שיודעים לחקור תקלה משני צדי הגבול. אם הפעולה אינה כבדה מספיק, העלות הזו יכולה לעלות על הרווח. זה בדיוק המקום שבו benchmark מבריק לא מספיק: צריך לראות את ה-flow כולו, מהשרת ועד המכשיר של המשתמש.

במילים אחרות, WebAssembly אינה תחליף ל-budget ביצועים. היא מחייבת budget ברור יותר: כמה זמן מותר לטעון, כמה CPU מותר לצרוך, ומה קורה כשהמכשיר חלש או כשמודול נכשל. רק אז אפשר לדעת אם הקרבה ל-machine code משרתת את המוצר ולא רק את השקף.

מה לקחת לפרודקשן

  • התחילו מצוואר הבקבוק המדוד: חישוב, רשת או rendering. WASM לא מתקנת בעיה שלא זוהתה.
  • שמרו את JavaScript בתפקיד שמחבר את האפליקציה, והעבירו למודול רק פונקציה ברורה וכבדה.
  • בדקו על מכשירים אמיתיים את גודל הקובץ, זמן הטעינה, הזיכרון וההשפעה על responsiveness.
  • תכננו את ה-API בין JavaScript ל-WASM כמו כל boundary אחר: inputs, types, errors ובעלות על זיכרון.
  • שקלו worker כשהעבודה כבדה מספיק כדי להתחרות ב-main thread.

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

"זה ממש לא אומר שזאת הרצאה על איך לבוא ולהחליף את JavaScript."

- דניאלה גרין

"אחד הפתרון שמצאנו הוא בעצם WebAssembly."

- דניאלה גרין

"הפעולות שאני צריכה לעשות עם הקוד כדי להגיע למשין קוד הן הרבה יותר קטנות."

- דניאלה גרין
[ פרקי ההרצאה ]
  1. 01:12
    למה WebAssembly נכנסת לשיחת performance
    דניאלה מציגה את ההייפ סביב WASM ומבהירה שהמטרה אינה להחליף JavaScript, אלא להבין איך שתי הטכנולוגיות משתלבות בפיתוח ווב.
  2. 03:34
    מ-Artlist לעיבוד סאונד בדפדפן
    הקונטקסט של Artlist הוא עיבוד סאונד על גבי הווב בלי להפריע לחוויית המשתמש, והפתרון שהצוות מצא כולל WebAssembly.
  3. 04:54
    מה WebAssembly מאפשרת להריץ
    WASM מאפשרת לקמפל שפות שאינן JavaScript, כגון C, C++ ו-Go, לפורמט שמוגדר על ידי W3C ויכול לרוץ בדפדפן.
  4. 07:58
    המחיר של JavaScript דינמית
    דניאלה עוברת על parsing, bytecode, אופטימיזציה ו-deoptimization של JIT, ומסבירה למה גמישות טיפוסים יכולה להוסיף עבודה בזמן ריצה.
  5. 11:41
    WASM בינארי קרוב יותר למכונה
    המודול נטען לצד נכסי הווב האחרים דרך JavaScript, אבל צריך פחות שלבי הכנה לפני קומפילציה והרצה ולכן מתאים לנתיבים חישוביים כבדים.
  6. 15:40
    טעינת מודול C מתוך React
    בדמו, fetch מביא קובץ WASM, response הופך ל-array buffer, WebAssembly.instantiate מחזיר instance, ו-JavaScript קוראת לפונקציה ש-exported מהמודול.
  7. 24:39
    Audio processing אמיתי ב-Artlist
    דניאלה מציגה ספריית אודיו ב-C שמטפלת בשינוי BPM של צליל ומוסברת כדרך לטפל בעומס של סאונד איכותי על גבי הווב.
  8. 31:40
    מגבלות: זיכרון, API של הדפדפן ודיבוג
    בשאלות הקהל עולה שהמודול מתקשר עם JavaScript כדי לגשת ליכולות הדפדפן, וששילוב טיפוסים וניהול זיכרון נעשים מורכבים יותר בדוגמה אמיתית.
[ נושאים ]

מה כוסה בהרצאה

#פרונטאנד #Frontend #Performance #WebAssembly
[ שאלות נפוצות ]

שאלות מההרצאה

האם WebAssembly מחליפה JavaScript?

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

למה WebAssembly יכולה להיות מהירה יותר בחישובים כבדים?

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

אילו use cases דניאלה מציגה ל-WebAssembly?

היא מציינת משחקים, גרפיקת 3D, video editing ו-music processing. הדוגמה המעשית שלה היא ספריית אודיו ב-C שמתקמפלת ל-WASM כדי לעבד סאונד ולהשפיע על BPM בדפדפן.

האם WebAssembly יכולה לגשת ישירות ל-file system או ל-API של הדפדפן?

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

[ קהילה ]

רוצה לדבר על ההרצאה?

הצטרף לקהילת המפתחים שלנו ב-WhatsApp.