WebAssembly (WASM) התחיל כדרך להריץ C++ בדפדפן. בשנת 2026 הוא רץ בכל מקום - דפדפנים, שרתים, רשתות edge, מכשירים משובצים - ומניע חלק מהאפליקציות התובעניות ביותר באינטרנט. מנוע הרינדור של Figma, Adobe Photoshop באינטרנט, עיבוד הווידאו של Google Meet ופלטפורמת ה-edge compute של Cloudflare כולם רצים על WebAssembly.
Chrome Platform Status מציב את WASM על כ-5.5% מכלל טעינות הדפים ב-Chrome נכון לתחילת 2026, עלייה מ-4.5% בשנה הקודמת. עם WASM 3.0 שהפך לתקן W3C ו-WASI שמתבגר לקראת 1.0, האקוסיסטם הגיע לנקודת מפנה.
המדריך הזה מכסה את כל מה שצריך לדעת כדי להתחיל לבנות עם WebAssembly.
מהו WebAssembly?
WebAssembly הוא פורמט הוראות בינארי שתוכנן כיעד קומפילציה. אתם כותבים קוד בשפה ברמה גבוהה (Rust, C, C++, Go, Kotlin), מקמפלים אותו ל-.wasm, ומריצים אותו בכל סביבה שיש בה WASM runtime - דפדפנים, Node.js, Cloudflare Workers, Wasmtime או Wasmer.
איך זה עובד
WASM הוא מכונה וירטואלית מבוססת-מחסנית. פונקציות דוחפות ומושכות ערכים ממחסנית אופרנדים. ה-runtime המארח (V8 ב-Chrome, SpiderMonkey ב-Firefox) עושה JIT-compile ל-bytecode של WASM לקוד מכונה מקורי, וזו הסיבה שהביצועים קרובים לנייטיב.
מאפיינים עיקריים:
- ביצוע מבודד (sandboxed): מודולי WASM יכולים לגשת רק למשאבים שהמארח מעניק במפורש. אין גישה למערכת הקבצים, לרשת או ל-OS אלא אם הורשה. זה שונה באופן בסיסי מקוד מקורי.
- זיכרון לינארי:
ArrayBufferרציף יחיד המשותף בין WASM לבין המארח. נתונים מורכבים (מחרוזות, structs) מועברים על ידי כתיבה לזיכרון ושיתוף מצביע. - מוגבל בטיפוסים: WASM תומך נטיבית רק בארבעה טיפוסים:
i32,i64,f32,f64. כל השאר (מחרוזות, מערכים, אובייקטים) דורש קידוד דרך זיכרון לינארי או דרך ה-Component Model. - נייד: אותו קובץ
.wasmבינארי רץ בכל פלטפורמה עם WASM runtime, ללא קומפילציה מחדש.
WASM מול JavaScript
WASM אינו מחליף את JavaScript. הוא משלים אותו.
| היבט | JavaScript | WebAssembly |
|---|---|---|
| Parsing | Parse + compile בזמן ריצה | בינארי מקומפל מראש, רק פענוח |
| מהירות ביצוע | מותאם JIT, משתנה | קרוב לנייטיב, עקבי |
| Startup | מהיר לסקריפטים קטנים | פענוח מהיר, צפוי |
| גישה ל-DOM | ישירה | עקיפה (דרך JS glue) |
| מתאים ביותר ל | UI, מניפולציה של DOM, טיפול באירועים | חישוב עתיר CPU |
| Garbage collection | מובנה | WasmGC (חדש), או ידני |
השתמשו ב-JavaScript לעבודת UI ו-DOM. השתמשו ב-WASM לחישובים כבדים: עיבוד תמונה, קידוד וידאו, סימולציות פיזיקה, קריפטוגרפיה, ניתוח נתונים.
WASM 3.0: מה חדש
WebAssembly 3.0 הפך לתקן W3C בספטמבר 2025, תוך תקנון של תשע תכונות שהיו בפיתוח במשך שנים.
| תכונה | מה היא מאפשרת |
|---|---|
| WasmGC | Garbage collection נייטיבי ב-WASM. שפות מנוהלות (Java, Kotlin, Dart) יכולות לקמפל ל-WASM מבלי לשלוח runtime GC משלהן. נתמך ב-Chrome 119+, Firefox 120+, Safari 18.2+. |
| Exception Handling | try/catch נייטיבי ב-WASM. בעבר, חריגות דרשו roundtrips יקרים ל-JavaScript. |
| Tail Calls | מאפשר רקורסיה יעילה ללא stack overflow. קריטי לשפות פונקציונליות. |
| Relaxed SIMD | הוראות וקטור של 128 ביט לעיבוד נתונים במקביל. מאפשר אופטימיזציות ספציפיות לחומרה. |
| Memory64 | שובר את מגבלת הזיכרון הלינארי של 4GB. נדרש לעיבוד נתונים בקנה מידה גדול. |
| Multi-memory | אזורי זיכרון עצמאיים מרובים במודול אחד. |
המשפיעה ביותר היא WasmGC. לפניה, קומפילציה של Java או Kotlin ל-WASM פירושה שליחה של garbage collector שלם כחלק מהבינארי, מה שניפח את גודל הקבצים. כעת ה-GC של הדפדפן עצמו מטפל בניהול הזיכרון עבור מודולי WASM, בדיוק כמו שהוא עושה עבור JavaScript.
WASI: WebAssembly מעבר לדפדפן
WASM בדפדפן הוא חזק, אך WASI (WebAssembly System Interface) הוא מה שהופך את WASM ל-runtime אוניברסלי. WASI מספק ממשקים מתוקננים למשאבי מערכת - קבצים, רשת, שעונים, מספרים אקראיים - המאפשרים למודולי WASM לרוץ מחוץ לדפדפן.
WASI Preview 2 (המהדורה היציבה הנוכחית) מגדיר את הממשקים הבאים:
wasi:filesystem- פעולות קובץ דרך capability handles (לא file descriptors מסורתיים)wasi:sockets- רשת TCP/UDPwasi:http- טיפול בבקשות/תגובות HTTPwasi:clocks- wall clock, monotonic clockwasi:random- אקראיות קריפטוגרפיתwasi:cli- ארגומנטים של שורת פקודה, משתני סביבה, stdio
העיקרון המרכזי הוא אבטחה מבוססת יכולות (capability-based): מודול WASM לא יכול לגשת למערכת הקבצים אלא אם המארח מעניק במפורש handle לספרייה ספציפית. זה הופך את WASI לבטוח באופן מהותי יותר מהרצת קבצי הפעלה מקוריים.
הדרך ל-WASI 1.0
WASI 0.3.0 (המוסיף פרימיטיבים של async/concurrency) צפוי ב-2026, ואחריו WASI 1.0. התוספת העיקרית היא async משולב שפה עם streaming I/O ללא העתקה.
ה-Component Model
מודולי WASM בסיסיים יכולים להחליף רק מספרים. ה-Component Model פותר מגבלה זו על ידי הוספת מערכת טיפוסים עשירה ושכבת composability על גבי WASM.
WIT (WebAssembly Interface Types)
WIT היא שפת הגדרת ממשקים המאפשרת לרכיבים להצהיר על ה-imports וה-exports שלהם עם טיפוסים עשירים - מחרוזות, records, lists, variants, enums - לא רק i32 ו-f64.
// calculator.wit package myorg:calculator@1.0.0; interface operations { record calculation { expression: string, result: f64, timestamp: u64, } add: func(a: f64, b: f64) -> f64; multiply: func(a: f64, b: f64) -> f64; history: func() -> list<calculation>; } world calculator { export operations; }
Toolchains כמו wit-bindgen מייצרים קישורים ספציפיים לשפה מקבצי WIT. רכיב Rust ורכיב Python יכולים להחליף מחרוזות, records ו-lists דרך חוזי WIT מבלי שאף צד יידע את שפת המימוש של הצד השני.
בניית מודול ה-WASM הראשון שלכם עם Rust
ל-Rust יש את ה-tooling הבוגר ביותר ל-WASM. בואו נבנה דוגמה מעשית: מודול עיבוד תמונה שרץ בדפדפן.
הקמה
# Install the WASM target for Rust rustup target add wasm32-unknown-unknown # Install wasm-pack (builds Rust to WASM + generates JS bindings) cargo install wasm-pack # Create a new library project cargo new --lib image-processor cd image-processor
הגדרת Cargo.toml
[package] name = "image-processor" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2"
כתיבת קוד Rust
// src/lib.rs use wasm_bindgen::prelude::*; /// Convert an image buffer to grayscale. /// Input: RGBA pixel data as a flat u8 array (4 bytes per pixel). /// Output: Modified in place for zero-copy performance. #[wasm_bindgen] pub fn grayscale(pixels: &mut [u8]) { for chunk in pixels.chunks_exact_mut(4) { let r = chunk[0] as f32; let g = chunk[1] as f32; let b = chunk[2] as f32; // ITU-R BT.709 luminance coefficients let gray = (0.2126 * r + 0.7152 * g + 0.0722 * b) as u8; chunk[0] = gray; chunk[1] = gray; chunk[2] = gray; // chunk[3] is alpha, leave unchanged } } /// Adjust brightness of an image. /// factor > 1.0 brightens, < 1.0 darkens. #[wasm_bindgen] pub fn adjust_brightness(pixels: &mut [u8], factor: f32) { for chunk in pixels.chunks_exact_mut(4) { chunk[0] = ((chunk[0] as f32 * factor).min(255.0)) as u8; chunk[1] = ((chunk[1] as f32 * factor).min(255.0)) as u8; chunk[2] = ((chunk[2] as f32 * factor).min(255.0)) as u8; } } /// Invert all colors in the image. #[wasm_bindgen] pub fn invert(pixels: &mut [u8]) { for chunk in pixels.chunks_exact_mut(4) { chunk[0] = 255 - chunk[0]; chunk[1] = 255 - chunk[1]; chunk[2] = 255 - chunk[2]; } } /// Calculate the average brightness of an image (0-255). #[wasm_bindgen] pub fn average_brightness(pixels: &[u8]) -> f32 { let mut total: f64 = 0.0; let pixel_count = pixels.len() / 4; for chunk in pixels.chunks_exact(4) { let luminance = 0.2126 * chunk[0] as f64 + 0.7152 * chunk[1] as f64 + 0.0722 * chunk[2] as f64; total += luminance; } (total / pixel_count as f64) as f32 }
בנייה
wasm-pack build --target web
זה מייצר ספרייה pkg/ עם:
image_processor_bg.wasm- הבינארי של WASM לאחר קומפילציהimage_processor.js- קוד glue של JavaScript עם הגדרות TypeScriptpackage.json- מוכן לפרסום ב-npm
שימוש ב-JavaScript
<!DOCTYPE html> <html> <head><title>WASM Image Processor</title></head> <body> <canvas id="canvas" width="800" height="600"></canvas> <button onclick="applyGrayscale()">Grayscale</button> <button onclick="applyBrightness()">Brighten</button> <button onclick="applyInvert()">Invert</button> <script type="module"> import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js"; let ctx; let imageData; async function setup() { await init(); const canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); // Load an image onto the canvas const img = new Image(); img.onload = () => { ctx.drawImage(img, 0, 0); imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); }; img.src = "photo.jpg"; } window.applyGrayscale = () => { grayscale(imageData.data); ctx.putImageData(imageData, 0, 0); }; window.applyBrightness = () => { adjust_brightness(imageData.data, 1.3); ctx.putImageData(imageData, 0, 0); }; window.applyInvert = () => { invert(imageData.data); ctx.putImageData(imageData, 0, 0); }; setup(); </script> </body> </html>
התובנה המרכזית: imageData.data הוא Uint8ClampedArray המגובה ב-ArrayBuffer. כשהוא מועבר ל-WASM, הוא משתף את אותו זיכרון - ללא העתקה. פונקציית ה-Rust משנה פיקסלים במקום, וצד ה-JavaScript רואה את השינויים מיד.
רמה נמוכה יותר: Instantiation ידני של WASM
אם אינכם רוצים להשתמש ב-wasm-bindgen, אתם יכולים לעשות instantiate למודולי WASM ישירות:
const response = await fetch("calculator.wasm"); const { instance } = await WebAssembly.instantiateStreaming(response, { env: { // Functions the WASM module can call log_result: (value) => console.log("Result:", value), }, }); // Call exported functions const { add, multiply } = instance.exports; console.log(add(5, 3)); // 8 console.log(multiply(4, 7)); // 28
זה שימושי כשאתם רוצים overhead מינימלי ולא צריכים אינטרופ עשיר של טיפוסים.
ביצועים: WASM מול JavaScript
בנצ'מרקים מהעולם האמיתי מראים האצות משמעותיות עבור משימות עתירות CPU:
| משימה | JavaScript | WASM | האצה |
|---|---|---|---|
| עיבוד תמונה 4K | 180ms | 8ms (עם SIMD) | 22x |
| שינוי גודל תמונה (4K) | 250ms | 45ms | 5.5x |
| סימולציית פיזיקה (10K ישויות) | מאבד פריימים | 60fps חלק | ~10x |
| ניתוח JSON (payload גדול) | 12ms | 3ms | 4x |
| Hashing קריפטוגרפי | 45ms | 6ms | 7.5x |
WASM רץ בערך ב-95% ממהירות קוד נייטיבי. הרווחים הגדולים ביותר מגיעים מ:
- ביצועים צפויים (ללא חימום JIT, ללא הפסקות GC)
- הוראות SIMD לעיבוד נתונים במקביל
- גישה ישירה לזיכרון ללא הפרעה של garbage collector
היכן WASM לא מהיר יותר: מניפולציה של DOM, חישובים קטנים, משימות חסומות I/O. JavaScript כבר מותאם לאלה.
מקרי שימוש בייצור
Figma: רינדור וקטורי בזמן אמת
מנוע הרינדור המרכזי של Figma הוא C++ שקומפל ל-WASM. כל צורה, gradient ואפקט מחושבים ב-WASM ומצוירים לאלמנט Canvas. זה מאפשר ל-Figma לטפל בעיצובים מורכבים עם אלפי שכבות ב-60fps בדפדפן - ביצועים שהיו בלתי אפשריים ב-JavaScript טהור.
Adobe Photoshop באינטרנט
Adobe העבירה פילטרים וכלים מרכזיים של Photoshop ל-WASM באמצעות Rust. הבנצ'מרקים שלהם מראים עיבוד תמונה 4K ב-22ms עם WASM SIMD לעומת 180ms ב-JavaScript - שיפור פי 8 שמאפשר תצוגות מקדימות של פילטרים בזמן אמת.
Cloudflare Workers
Cloudflare מריצה מודולי WASM ב-V8 isolates על פני 330+ מיקומי edge. Cold starts הם 1-5ms (לעומת 100-500ms ל-serverless מבוסס קונטיינר). בפברואר 2026 הם פרסו inference של Llama-3-8b ברחבי רשת ה-edge שלהם באמצעות WASM.
Google Meet
Background blur ורקעים וירטואליים ב-Google Meet משתמשים ב-WASM עם SIMD לעיבוד וידאו בזמן אמת. מודול ה-WASM מעבד כל פריים וידאו מהר מספיק כדי לשמור על וידאו חלק ב-30fps.
תמיכת דפדפנים (2026)
| תכונה | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Core WASM | מלאה | מלאה | מלאה | מלאה |
| Threads | כן | כן | כן | כן |
| SIMD (128-bit) | כן | כן | כן | כן |
| WasmGC | 119+ | 120+ | 18.2+ | כן |
| Exception Handling | כן | כן | כן | כן |
| Memory64 | כן | כן | חלקית | כן |
כל הדפדפנים המרכזיים תומכים במלואם ב-WASM. התכונות החדשות יותר (WasmGC, Exception Handling) הגיעו לזמינות רחבה.
הפניית כלים
| כלי | מטרה | התקנה |
|---|---|---|
| wasm-pack | בניית Rust ל-WASM, יצירת חבילות npm | cargo install wasm-pack |
| wasm-bindgen | קישורי אינטרופ Rust/JS (משמש את wasm-pack) | תלות ב-Cargo.toml |
| wasm-opt | אופטימיזציית גודל בינארי (50%+ הפחתה) | חלק מ-Binaryen: brew install binaryen |
| wit-bindgen | יצירת קישורים מקבצי WIT | cargo install wit-bindgen-cli |
| Wasmtime | WASM runtime בצד שרת (מימוש ייחוס של WASI) | brew install wasmtime |
| Wasmer | WASM runtime אלטרנטיבי עם תמיכת WASI | curl https://get.wasmer.io -sSfL | sh |
| wasm-feature-detect | זיהוי תכונות דפדפן בזמן ריצה | npm install wasm-feature-detect |
אופטימיזציית גודל בינארי
בינארים של WASM יכולים להיות גדולים. הנה איך לכווץ אותם:
# Cargo.toml [profile.release] opt-level = "z" # Optimize for size lto = true # Link-time optimization codegen-units = 1 # Better optimization, slower compile strip = true # Strip debug symbols
# Build in release mode wasm-pack build --release --target web # Further optimize with wasm-opt wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm
מודול WASM טיפוסי של Rust יורד מ-500KB לפחות מ-50KB עם האופטימיזציות הללו.
מפת דרכים להתחלה
סיכום
WebAssembly אינו יותר ניסיוני. זוהי טכנולוגיית ייצור המשמשת חלק מהאפליקציות התובעניות ביותר באינטרנט. ביצועים קרובים לנייטיב, אבטחה מבודדת וניידות אוניברסלית - אף יעד קומפילציה אחר לא נותן לכם את שלושת אלה.
אינכם צריכים לכתוב מחדש את כל האפליקציה שלכם ב-WASM. התחילו עם פונקציה אחת עתירת CPU - פילטר תמונה, parser נתונים, חישוב פיזיקה - קמפלו אותה ל-WASM וקראו לה מ-JavaScript. מדדו את ההבדל. לאחר מכן החליטו היכן עוד WASM יכול לעזור.
הכלים בוגרים, תמיכת הדפדפנים אוניברסלית, והאקוסיסטם גדל. אם אתם כותבים Rust, אתם כבר פקודה אחת מהדפדפן.
רשימת בדיקה להתחלה:
- Rust ו-wasm-pack מותקנים
- מודול WASM ראשון נבנה ורץ בדפדפן
- אינטרופ עם JavaScript עובד (קריאה ל-WASM מ-JS)
- Release build עם אופטימיזציות גודל מיושמות
- ביצועים נמדדו מול מקבילה ב-JavaScript טהור
- WASI נחקר עם Wasmtime למקרי שימוש בצד שרת