spinny:~/writing $ vim webassembly-wasm-complete-guide.md
1~2WebAssembly (WASM) התחיל כדרך להריץ C++ בדפדפן. בשנת 2026 הוא רץ בכל מקום - דפדפנים, שרתים, רשתות edge, מכשירים משובצים - ומניע חלק מהאפליקציות התובעניות ביותר באינטרנט. מנוע הרינדור של Figma, Adobe Photoshop באינטרנט, עיבוד הווידאו של Google Meet ופלטפורמת ה-edge compute של Cloudflare כולם רצים על WebAssembly.3~4Chrome Platform Status מציב את WASM על כ-5.5% מכלל טעינות הדפים ב-Chrome נכון לתחילת 2026, עלייה מ-4.5% בשנה הקודמת. עם WASM 3.0 שהפך לתקן W3C ו-WASI שמתבגר לקראת 1.0, האקוסיסטם הגיע לנקודת מפנה.5~6המדריך הזה מכסה את כל מה שצריך לדעת כדי להתחיל לבנות עם WebAssembly.7~8## מהו WebAssembly?9~10WebAssembly הוא פורמט הוראות בינארי שתוכנן כיעד קומפילציה. אתם כותבים קוד בשפה ברמה גבוהה (Rust, C, C++, Go, Kotlin), מקמפלים אותו ל-`.wasm`, ומריצים אותו בכל סביבה שיש בה WASM runtime - דפדפנים, Node.js, Cloudflare Workers, Wasmtime או Wasmer.11~12```mermaid13graph LR14 Rust[Rust / C / C++] --> Compiler[Compiler]15 Compiler --> WASM[.wasm Binary]16 WASM --> Browser[Browser V8/SpiderMonkey]17 WASM --> Server[Server Wasmtime]18 WASM --> Edge[Edge Cloudflare Workers]19 WASM --> Embedded[Embedded WAMR]20```21~22### איך זה עובד23~24WASM הוא **מכונה וירטואלית מבוססת-מחסנית**. פונקציות דוחפות ומושכות ערכים ממחסנית אופרנדים. ה-runtime המארח (V8 ב-Chrome, SpiderMonkey ב-Firefox) עושה JIT-compile ל-bytecode של WASM לקוד מכונה מקורי, וזו הסיבה שהביצועים קרובים לנייטיב.25~26מאפיינים עיקריים:27~28- **ביצוע מבודד (sandboxed)**: מודולי WASM יכולים לגשת רק למשאבים שהמארח מעניק במפורש. אין גישה למערכת הקבצים, לרשת או ל-OS אלא אם הורשה. זה שונה באופן בסיסי מקוד מקורי.29- **זיכרון לינארי**: `ArrayBuffer` רציף יחיד המשותף בין WASM לבין המארח. נתונים מורכבים (מחרוזות, structs) מועברים על ידי כתיבה לזיכרון ושיתוף מצביע.30- **מוגבל בטיפוסים**: WASM תומך נטיבית רק בארבעה טיפוסים: `i32`, `i64`, `f32`, `f64`. כל השאר (מחרוזות, מערכים, אובייקטים) דורש קידוד דרך זיכרון לינארי או דרך ה-Component Model.31- **נייד**: אותו קובץ `.wasm` בינארי רץ בכל פלטפורמה עם WASM runtime, ללא קומפילציה מחדש.32~33### WASM מול JavaScript34~35WASM אינו מחליף את JavaScript. הוא משלים אותו.36~37| היבט | JavaScript | WebAssembly |38|--------|-----------|-------------|39| **Parsing** | Parse + compile בזמן ריצה | בינארי מקומפל מראש, רק פענוח |40| **מהירות ביצוע** | מותאם JIT, משתנה | קרוב לנייטיב, עקבי |41| **Startup** | מהיר לסקריפטים קטנים | פענוח מהיר, צפוי |42| **גישה ל-DOM** | ישירה | עקיפה (דרך JS glue) |43| **מתאים ביותר ל** | UI, מניפולציה של DOM, טיפול באירועים | חישוב עתיר CPU |44| **Garbage collection** | מובנה | WasmGC (חדש), או ידני |45~46השתמשו ב-JavaScript לעבודת UI ו-DOM. השתמשו ב-WASM לחישובים כבדים: עיבוד תמונה, קידוד וידאו, סימולציות פיזיקה, קריפטוגרפיה, ניתוח נתונים.47~48## WASM 3.0: מה חדש49~50WebAssembly 3.0 הפך לתקן W3C בספטמבר 2025, תוך תקנון של תשע תכונות שהיו בפיתוח במשך שנים.51~52| תכונה | מה היא מאפשרת |53|---------|----------------|54| **WasmGC** | Garbage collection נייטיבי ב-WASM. שפות מנוהלות (Java, Kotlin, Dart) יכולות לקמפל ל-WASM מבלי לשלוח runtime GC משלהן. נתמך ב-Chrome 119+, Firefox 120+, Safari 18.2+. |55| **Exception Handling** | `try`/`catch` נייטיבי ב-WASM. בעבר, חריגות דרשו roundtrips יקרים ל-JavaScript. |56| **Tail Calls** | מאפשר רקורסיה יעילה ללא stack overflow. קריטי לשפות פונקציונליות. |57| **Relaxed SIMD** | הוראות וקטור של 128 ביט לעיבוד נתונים במקביל. מאפשר אופטימיזציות ספציפיות לחומרה. |58| **Memory64** | שובר את מגבלת הזיכרון הלינארי של 4GB. נדרש לעיבוד נתונים בקנה מידה גדול. |59| **Multi-memory** | אזורי זיכרון עצמאיים מרובים במודול אחד. |60~61המשפיעה ביותר היא **WasmGC**. לפניה, קומפילציה של Java או Kotlin ל-WASM פירושה שליחה של garbage collector שלם כחלק מהבינארי, מה שניפח את גודל הקבצים. כעת ה-GC של הדפדפן עצמו מטפל בניהול הזיכרון עבור מודולי WASM, בדיוק כמו שהוא עושה עבור JavaScript.62~63## WASI: WebAssembly מעבר לדפדפן64~65WASM בדפדפן הוא חזק, אך **WASI (WebAssembly System Interface)** הוא מה שהופך את WASM ל-runtime אוניברסלי. WASI מספק ממשקים מתוקננים למשאבי מערכת - קבצים, רשת, שעונים, מספרים אקראיים - המאפשרים למודולי WASM לרוץ מחוץ לדפדפן.66~67```mermaid68graph TD69 subgraph "Browser"70 B[WASM Module] --> Web[Web APIs\nDOM, Fetch, Canvas]71 end72~73 subgraph "Server / Edge / Embedded"74 S[WASM Module] --> WASI[WASI Interfaces]75 WASI --> FS[wasi:filesystem]76 WASI --> Net[wasi:sockets]77 WASI --> HTTP[wasi:http]78 WASI --> Clock[wasi:clocks]79 WASI --> Rand[wasi:random]80 end81```82~83WASI Preview 2 (המהדורה היציבה הנוכחית) מגדיר את הממשקים הבאים:84~85- `wasi:filesystem` - פעולות קובץ דרך capability handles (לא file descriptors מסורתיים)86- `wasi:sockets` - רשת TCP/UDP87- `wasi:http` - טיפול בבקשות/תגובות HTTP88- `wasi:clocks` - wall clock, monotonic clock89- `wasi:random` - אקראיות קריפטוגרפית90- `wasi:cli` - ארגומנטים של שורת פקודה, משתני סביבה, stdio91~92העיקרון המרכזי הוא **אבטחה מבוססת יכולות (capability-based)**: מודול WASM לא יכול לגשת למערכת הקבצים אלא אם המארח מעניק במפורש handle לספרייה ספציפית. זה הופך את WASI לבטוח באופן מהותי יותר מהרצת קבצי הפעלה מקוריים.93~94### הדרך ל-WASI 1.095~96WASI 0.3.0 (המוסיף פרימיטיבים של async/concurrency) צפוי ב-2026, ואחריו WASI 1.0. התוספת העיקרית היא async משולב שפה עם streaming I/O ללא העתקה.97~98## ה-Component Model99~100מודולי WASM בסיסיים יכולים להחליף רק מספרים. ה-**Component Model** פותר מגבלה זו על ידי הוספת מערכת טיפוסים עשירה ושכבת composability על גבי WASM.101~102### WIT (WebAssembly Interface Types)103~104WIT היא שפת הגדרת ממשקים המאפשרת לרכיבים להצהיר על ה-imports וה-exports שלהם עם טיפוסים עשירים - מחרוזות, records, lists, variants, enums - לא רק `i32` ו-`f64`.105~106```wit107// calculator.wit108package myorg:calculator@1.0.0;109~110interface operations {111 record calculation {112 expression: string,113 result: f64,114 timestamp: u64,115 }116~117 add: func(a: f64, b: f64) -> f64;118 multiply: func(a: f64, b: f64) -> f64;119 history: func() -> list<calculation>;120}121~122world calculator {123 export operations;124}125```126~127Toolchains כמו `wit-bindgen` מייצרים קישורים ספציפיים לשפה מקבצי WIT. רכיב Rust ורכיב Python יכולים להחליף מחרוזות, records ו-lists דרך חוזי WIT מבלי שאף צד יידע את שפת המימוש של הצד השני.128~129## בניית מודול ה-WASM הראשון שלכם עם Rust130~131ל-Rust יש את ה-tooling הבוגר ביותר ל-WASM. בואו נבנה דוגמה מעשית: מודול עיבוד תמונה שרץ בדפדפן.132~133### הקמה134~135```bash136# Install the WASM target for Rust137rustup target add wasm32-unknown-unknown138~139# Install wasm-pack (builds Rust to WASM + generates JS bindings)140cargo install wasm-pack141~142# Create a new library project143cargo new --lib image-processor144cd image-processor145```146~147### הגדרת Cargo.toml148~149```toml150[package]151name = "image-processor"152version = "0.1.0"153edition = "2021"154~155[lib]156crate-type = ["cdylib"]157~158[dependencies]159wasm-bindgen = "0.2"160```161~162### כתיבת קוד Rust163~164```rust165// src/lib.rs166use wasm_bindgen::prelude::*;167~168/// Convert an image buffer to grayscale.169/// Input: RGBA pixel data as a flat u8 array (4 bytes per pixel).170/// Output: Modified in place for zero-copy performance.171#[wasm_bindgen]172pub fn grayscale(pixels: &mut [u8]) {173 for chunk in pixels.chunks_exact_mut(4) {174 let r = chunk[0] as f32;175 let g = chunk[1] as f32;176 let b = chunk[2] as f32;177 // ITU-R BT.709 luminance coefficients178 let gray = (0.2126 * r + 0.7152 * g + 0.0722 * b) as u8;179 chunk[0] = gray;180 chunk[1] = gray;181 chunk[2] = gray;182 // chunk[3] is alpha, leave unchanged183 }184}185~186/// Adjust brightness of an image.187/// factor > 1.0 brightens, < 1.0 darkens.188#[wasm_bindgen]189pub fn adjust_brightness(pixels: &mut [u8], factor: f32) {190 for chunk in pixels.chunks_exact_mut(4) {191 chunk[0] = ((chunk[0] as f32 * factor).min(255.0)) as u8;192 chunk[1] = ((chunk[1] as f32 * factor).min(255.0)) as u8;193 chunk[2] = ((chunk[2] as f32 * factor).min(255.0)) as u8;194 }195}196~197/// Invert all colors in the image.198#[wasm_bindgen]199pub fn invert(pixels: &mut [u8]) {200 for chunk in pixels.chunks_exact_mut(4) {201 chunk[0] = 255 - chunk[0];202 chunk[1] = 255 - chunk[1];203 chunk[2] = 255 - chunk[2];204 }205}206~207/// Calculate the average brightness of an image (0-255).208#[wasm_bindgen]209pub fn average_brightness(pixels: &[u8]) -> f32 {210 let mut total: f64 = 0.0;211 let pixel_count = pixels.len() / 4;212 for chunk in pixels.chunks_exact(4) {213 let luminance = 0.2126 * chunk[0] as f64214 + 0.7152 * chunk[1] as f64215 + 0.0722 * chunk[2] as f64;216 total += luminance;217 }218 (total / pixel_count as f64) as f32219}220```221~222### בנייה223~224```bash225wasm-pack build --target web226```227~228זה מייצר ספרייה `pkg/` עם:229- `image_processor_bg.wasm` - הבינארי של WASM לאחר קומפילציה230- `image_processor.js` - קוד glue של JavaScript עם הגדרות TypeScript231- `package.json` - מוכן לפרסום ב-npm232~233### שימוש ב-JavaScript234~235```html236<!DOCTYPE html>237<html>238<head><title>WASM Image Processor</title></head>239<body>240 <canvas id="canvas" width="800" height="600"></canvas>241 <button onclick="applyGrayscale()">Grayscale</button>242 <button onclick="applyBrightness()">Brighten</button>243 <button onclick="applyInvert()">Invert</button>244~245 <script type="module">246 import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js";247~248 let ctx;249 let imageData;250~251 async function setup() {252 await init();253 const canvas = document.getElementById("canvas");254 ctx = canvas.getContext("2d");255~256 // Load an image onto the canvas257 const img = new Image();258 img.onload = () => {259 ctx.drawImage(img, 0, 0);260 imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);261 };262 img.src = "photo.jpg";263 }264~265 window.applyGrayscale = () => {266 grayscale(imageData.data);267 ctx.putImageData(imageData, 0, 0);268 };269~270 window.applyBrightness = () => {271 adjust_brightness(imageData.data, 1.3);272 ctx.putImageData(imageData, 0, 0);273 };274~275 window.applyInvert = () => {276 invert(imageData.data);277 ctx.putImageData(imageData, 0, 0);278 };279~280 setup();281 </script>282</body>283</html>284```285~286התובנה המרכזית: `imageData.data` הוא `Uint8ClampedArray` המגובה ב-`ArrayBuffer`. כשהוא מועבר ל-WASM, הוא משתף את אותו זיכרון - ללא העתקה. פונקציית ה-Rust משנה פיקסלים במקום, וצד ה-JavaScript רואה את השינויים מיד.287~288## רמה נמוכה יותר: Instantiation ידני של WASM289~290אם אינכם רוצים להשתמש ב-`wasm-bindgen`, אתם יכולים לעשות instantiate למודולי WASM ישירות:291~292```javascript293const response = await fetch("calculator.wasm");294const { instance } = await WebAssembly.instantiateStreaming(response, {295 env: {296 // Functions the WASM module can call297 log_result: (value) => console.log("Result:", value),298 },299});300~301// Call exported functions302const { add, multiply } = instance.exports;303console.log(add(5, 3)); // 8304console.log(multiply(4, 7)); // 28305```306~307זה שימושי כשאתם רוצים overhead מינימלי ולא צריכים אינטרופ עשיר של טיפוסים.308~309## ביצועים: WASM מול JavaScript310~311בנצ'מרקים מהעולם האמיתי מראים האצות משמעותיות עבור משימות עתירות CPU:312~313| משימה | JavaScript | WASM | האצה |314|------|-----------|------|---------|315| עיבוד תמונה 4K | 180ms | 8ms (עם SIMD) | 22x |316| שינוי גודל תמונה (4K) | 250ms | 45ms | 5.5x |317| סימולציית פיזיקה (10K ישויות) | מאבד פריימים | 60fps חלק | ~10x |318| ניתוח JSON (payload גדול) | 12ms | 3ms | 4x |319| Hashing קריפטוגרפי | 45ms | 6ms | 7.5x |320~321WASM רץ בערך ב-95% ממהירות קוד נייטיבי. הרווחים הגדולים ביותר מגיעים מ:322- ביצועים צפויים (ללא חימום JIT, ללא הפסקות GC)323- הוראות SIMD לעיבוד נתונים במקביל324- גישה ישירה לזיכרון ללא הפרעה של garbage collector325~326היכן WASM לא מהיר יותר: מניפולציה של DOM, חישובים קטנים, משימות חסומות I/O. JavaScript כבר מותאם לאלה.327~328## מקרי שימוש בייצור329~330### Figma: רינדור וקטורי בזמן אמת331~332מנוע הרינדור המרכזי של Figma הוא C++ שקומפל ל-WASM. כל צורה, gradient ואפקט מחושבים ב-WASM ומצוירים לאלמנט Canvas. זה מאפשר ל-Figma לטפל בעיצובים מורכבים עם אלפי שכבות ב-60fps בדפדפן - ביצועים שהיו בלתי אפשריים ב-JavaScript טהור.333~334### Adobe Photoshop באינטרנט335~336Adobe העבירה פילטרים וכלים מרכזיים של Photoshop ל-WASM באמצעות Rust. הבנצ'מרקים שלהם מראים עיבוד תמונה 4K ב-22ms עם WASM SIMD לעומת 180ms ב-JavaScript - שיפור פי 8 שמאפשר תצוגות מקדימות של פילטרים בזמן אמת.337~338### Cloudflare Workers339~340Cloudflare מריצה מודולי WASM ב-V8 isolates על פני 330+ מיקומי edge. Cold starts הם 1-5ms (לעומת 100-500ms ל-serverless מבוסס קונטיינר). בפברואר 2026 הם פרסו inference של Llama-3-8b ברחבי רשת ה-edge שלהם באמצעות WASM.341~342### Google Meet343~344Background blur ורקעים וירטואליים ב-Google Meet משתמשים ב-WASM עם SIMD לעיבוד וידאו בזמן אמת. מודול ה-WASM מעבד כל פריים וידאו מהר מספיק כדי לשמור על וידאו חלק ב-30fps.345~346## תמיכת דפדפנים (2026)347~348| תכונה | Chrome | Firefox | Safari | Edge |349|---------|--------|---------|--------|------|350| Core WASM | מלאה | מלאה | מלאה | מלאה |351| Threads | כן | כן | כן | כן |352| SIMD (128-bit) | כן | כן | כן | כן |353| WasmGC | 119+ | 120+ | 18.2+ | כן |354| Exception Handling | כן | כן | כן | כן |355| Memory64 | כן | כן | חלקית | כן |356~357כל הדפדפנים המרכזיים תומכים במלואם ב-WASM. התכונות החדשות יותר (WasmGC, Exception Handling) הגיעו לזמינות רחבה.358~359## הפניית כלים360~361| כלי | מטרה | התקנה |362|------|---------|---------|363| **wasm-pack** | בניית Rust ל-WASM, יצירת חבילות npm | `cargo install wasm-pack` |364| **wasm-bindgen** | קישורי אינטרופ Rust/JS (משמש את wasm-pack) | תלות ב-Cargo.toml |365| **wasm-opt** | אופטימיזציית גודל בינארי (50%+ הפחתה) | חלק מ-Binaryen: `brew install binaryen` |366| **wit-bindgen** | יצירת קישורים מקבצי WIT | `cargo install wit-bindgen-cli` |367| **Wasmtime** | WASM runtime בצד שרת (מימוש ייחוס של WASI) | `brew install wasmtime` |368| **Wasmer** | WASM runtime אלטרנטיבי עם תמיכת WASI | `curl https://get.wasmer.io -sSfL \| sh` |369| **wasm-feature-detect** | זיהוי תכונות דפדפן בזמן ריצה | `npm install wasm-feature-detect` |370~371### אופטימיזציית גודל בינארי372~373בינארים של WASM יכולים להיות גדולים. הנה איך לכווץ אותם:374~375```toml376# Cargo.toml377[profile.release]378opt-level = "z" # Optimize for size379lto = true # Link-time optimization380codegen-units = 1 # Better optimization, slower compile381strip = true # Strip debug symbols382```383~384```bash385# Build in release mode386wasm-pack build --release --target web387~388# Further optimize with wasm-opt389wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm390```391~392מודול WASM טיפוסי של Rust יורד מ-500KB לפחות מ-50KB עם האופטימיזציות הללו.393~394## מפת דרכים להתחלה395~396```mermaid397flowchart TD398 A[Week 1: Basics] --> B[Week 2: Real Project]399 B --> C[Week 3: WASI and Server-side]400 C --> D[Month 2+: Production]401~402 A --> A1[Install Rust + wasm-pack]403 A --> A2[Build hello-world WASM module]404 A --> A3[Call WASM functions from JavaScript]405~406 B --> B1[Build image processor or game physics]407 B --> B2[Use wasm-bindgen for rich types]408 B --> B3[Benchmark against pure JS]409~410 C --> C1[Run WASM with Wasmtime]411 C --> C2[Explore WASI interfaces]412 C --> C3[Try Component Model with WIT]413~414 D --> D1[Optimize binary size]415 D --> D2[Use SIMD for parallelism]416 D --> D3[Deploy to Cloudflare Workers or browser]417```418~419## סיכום420~421WebAssembly אינו יותר ניסיוני. זוהי טכנולוגיית ייצור המשמשת חלק מהאפליקציות התובעניות ביותר באינטרנט. ביצועים קרובים לנייטיב, אבטחה מבודדת וניידות אוניברסלית - אף יעד קומפילציה אחר לא נותן לכם את שלושת אלה.422~423אינכם צריכים לכתוב מחדש את כל האפליקציה שלכם ב-WASM. התחילו עם פונקציה אחת עתירת CPU - פילטר תמונה, parser נתונים, חישוב פיזיקה - קמפלו אותה ל-WASM וקראו לה מ-JavaScript. מדדו את ההבדל. לאחר מכן החליטו היכן עוד WASM יכול לעזור.424~425הכלים בוגרים, תמיכת הדפדפנים אוניברסלית, והאקוסיסטם גדל. אם אתם כותבים Rust, אתם כבר פקודה אחת מהדפדפן.426~427> **רשימת בדיקה להתחלה:**428>429> - [x] Rust ו-wasm-pack מותקנים430> - [x] מודול WASM ראשון נבנה ורץ בדפדפן431> - [x] אינטרופ עם JavaScript עובד (קריאה ל-WASM מ-JS)432> - [x] Release build עם אופטימיזציות גודל מיושמות433> - [x] ביצועים נמדדו מול מקבילה ב-JavaScript טהור434> - [x] WASI נחקר עם Wasmtime למקרי שימוש בצד שרת435~
NORMAL · webassembly-wasm-complete-guide.md [readonly]435 lines · :q to close