spinny:~/writing $ less webassembly-wasm-complete-guide.md
12WebAssembly (WASM) bermula sebagai cara untuk menjalankan C++ dalam pelayar. Pada 2026, ia berjalan di mana-mana - pelayar, pelayan, rangkaian edge, peranti terbenam - dan menggerakkan beberapa aplikasi paling mencabar di web. Enjin rendering Figma, Adobe Photoshop di web, pemprosesan video Google Meet, dan platform edge compute Cloudflare semuanya berjalan pada WebAssembly.34Chrome Platform Status meletakkan WASM pada kira-kira 5.5% daripada semua pemuatan halaman Chrome pada awal 2026, meningkat daripada 4.5% tahun sebelumnya. Dengan WASM 3.0 menjadi standard W3C dan WASI matang menuju 1.0, ekosistem telah mencapai titik perubahan.56Panduan ini merangkumi segala yang anda perlu tahu untuk mula membina dengan WebAssembly.78## Apa itu WebAssembly?910WebAssembly ialah format arahan binari yang direka sebagai sasaran kompilasi. Anda menulis kod dalam bahasa peringkat tinggi (Rust, C, C++, Go, Kotlin), mengompilkannya ke `.wasm`, dan menjalankannya dalam sebarang persekitaran yang mempunyai WASM runtime - pelayar, Node.js, Cloudflare Workers, Wasmtime, atau Wasmer.1112```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```2122### Cara Ia Berfungsi2324WASM ialah **mesin maya berasaskan stack**. Fungsi menolak dan memuncakkan nilai pada operand stack. Host runtime (V8 dalam Chrome, SpiderMonkey dalam Firefox) mengkompil-JIT bytecode WASM ke kod mesin asli, itulah sebabnya prestasi hampir setara dengan native.2526Ciri-ciri utama:2728- **Pelaksanaan sandboxed**: Modul WASM hanya boleh mengakses sumber yang diberikan secara eksplisit oleh host. Tiada filesystem, tiada rangkaian, tiada akses OS melainkan dibenarkan. Ini berbeza secara asas daripada kod native.29- **Memori linear**: satu `ArrayBuffer` bersambung yang dikongsi antara WASM dan host. Data kompleks (string, struct) dipindahkan dengan menulis ke memori dan berkongsi pointer.30- **Terhad jenis**: WASM menyokong secara native hanya empat jenis: `i32`, `i64`, `f32`, `f64`. Segala-galanya yang lain (string, array, objek) memerlukan pengekodan melalui memori linear atau Component Model.31- **Mudah alih**: binari `.wasm` yang sama berjalan pada mana-mana platform dengan WASM runtime, tanpa kompilasi semula.3233### WASM vs JavaScript3435WASM tidak menggantikan JavaScript. Ia melengkapinya.3637| Aspek | JavaScript | WebAssembly |38|--------|-----------|-------------|39| **Parsing** | Parse + compile pada runtime | Binari pra-kompil, hanya decode |40| **Kelajuan pelaksanaan** | Dioptimumkan JIT, berubah-ubah | Hampir native, konsisten |41| **Startup** | Pantas untuk skrip kecil | Decode pantas, boleh diramal |42| **Akses DOM** | Langsung | Tidak langsung (melalui JS glue) |43| **Terbaik untuk** | UI, manipulasi DOM, pengendalian event | Pengkomputeran intensif CPU |44| **Garbage collection** | Terbina dalam | WasmGC (baru), atau manual |4546Gunakan JavaScript untuk kerja UI dan DOM. Gunakan WASM untuk pengkomputeran berat: pemprosesan imej, pengekodan video, simulasi fizik, kriptografi, parsing data.4748## WASM 3.0: Apa yang Baru4950WebAssembly 3.0 menjadi standard W3C pada September 2025, menstandardkan sembilan ciri yang telah dalam pembangunan selama bertahun-tahun.5152| Ciri | Apa yang Diaktifkan |53|---------|----------------|54| **WasmGC** | Garbage collection native dalam WASM. Bahasa terurus (Java, Kotlin, Dart) boleh dikompil ke WASM tanpa menghantar runtime GC mereka sendiri. Disokong dalam Chrome 119+, Firefox 120+, Safari 18.2+. |55| **Exception Handling** | `try`/`catch` native dalam WASM. Sebelum ini, pengecualian memerlukan roundtrip mahal ke JavaScript. |56| **Tail Calls** | Mendayakan rekursi yang cekap tanpa stack overflow. Kritikal untuk bahasa fungsian. |57| **Relaxed SIMD** | Arahan vektor 128-bit untuk pemprosesan data selari. Mendayakan pengoptimuman khusus hardware. |58| **Memory64** | Memecahkan had memori linear 4GB. Diperlukan untuk pemprosesan data berskala besar. |59| **Multi-memory** | Pelbagai kawasan memori bebas dalam satu modul. |6061Yang paling berkesan ialah **WasmGC**. Sebelum ia, mengompil Java atau Kotlin ke WASM bermakna menghantar keseluruhan garbage collector sebagai sebahagian daripada binari, membengkakkan saiz fail. Kini GC pelayar sendiri mengendalikan pengurusan memori untuk modul WASM, sama seperti yang dilakukannya untuk JavaScript.6263## WASI: WebAssembly Melangkaui Pelayar6465WASM dalam pelayar adalah berkuasa, tetapi **WASI (WebAssembly System Interface)** adalah yang menjadikan WASM sebagai runtime universal. WASI menyediakan antara muka standard untuk sumber sistem - fail, rangkaian, jam, nombor rawak - membenarkan modul WASM berjalan di luar pelayar.6667```mermaid68graph TD69 subgraph "Browser"70 B[WASM Module] --> Web[Web APIs\nDOM, Fetch, Canvas]71 end7273 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```8283WASI Preview 2 (keluaran stabil semasa) mentakrifkan antara muka berikut:8485- `wasi:filesystem` - operasi fail melalui capability handles (bukan file descriptor tradisional)86- `wasi:sockets` - rangkaian TCP/UDP87- `wasi:http` - pengendalian request/response HTTP88- `wasi:clocks` - wall clock, monotonic clock89- `wasi:random` - kerawakan kriptografi90- `wasi:cli` - argumen baris arahan, pembolehubah persekitaran, stdio9192Prinsip utama ialah **keselamatan berasaskan kapabiliti**: modul WASM tidak boleh mengakses filesystem melainkan host secara eksplisit memberikan handle ke direktori tertentu. Ini menjadikan WASI secara asas lebih selamat daripada menjalankan executable native.9394### Laluan ke WASI 1.09596WASI 0.3.0 (menambah primitif async/concurrency) dijangka pada 2026, dengan WASI 1.0 akan menyusul. Tambahan utama ialah async bersepadu bahasa dengan streaming I/O zero-copy.9798## Component Model99100Modul WASM teras hanya boleh menukar nombor. **Component Model** menyelesaikan had ini dengan menambah sistem jenis yang kaya dan lapisan composability di atas WASM.101102### WIT (WebAssembly Interface Types)103104WIT ialah Interface Definition Language yang membolehkan komponen mengisytiharkan import dan eksport mereka dengan jenis yang kaya - string, record, list, variant, enum - bukan hanya `i32` dan `f64`.105106```wit107// calculator.wit108package myorg:calculator@1.0.0;109110interface operations {111 record calculation {112 expression: string,113 result: f64,114 timestamp: u64,115 }116117 add: func(a: f64, b: f64) -> f64;118 multiply: func(a: f64, b: f64) -> f64;119 history: func() -> list<calculation>;120}121122world calculator {123 export operations;124}125```126127Toolchain seperti `wit-bindgen` menghasilkan binding khusus bahasa daripada fail WIT. Komponen Rust dan komponen Python boleh menukar string, record, dan list melalui kontrak WIT tanpa mana-mana pihak mengetahui bahasa pelaksanaan pihak lain.128129## Membina Modul WASM Pertama Anda dengan Rust130131Rust mempunyai tooling WASM paling matang. Mari kita bina contoh praktikal: modul pemprosesan imej yang berjalan dalam pelayar.132133### Persediaan134135```bash136# Install the WASM target for Rust137rustup target add wasm32-unknown-unknown138139# Install wasm-pack (builds Rust to WASM + generates JS bindings)140cargo install wasm-pack141142# Create a new library project143cargo new --lib image-processor144cd image-processor145```146147### Konfigurasikan Cargo.toml148149```toml150[package]151name = "image-processor"152version = "0.1.0"153edition = "2021"154155[lib]156crate-type = ["cdylib"]157158[dependencies]159wasm-bindgen = "0.2"160```161162### Tulis Kod Rust163164```rust165// src/lib.rs166use wasm_bindgen::prelude::*;167168/// 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}185186/// 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}196197/// 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}206207/// 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```221222### Bina223224```bash225wasm-pack build --target web226```227228Ini menghasilkan direktori `pkg/` dengan:229- `image_processor_bg.wasm` - binari WASM yang telah dikompil230- `image_processor.js` - kod glue JavaScript dengan definisi TypeScript231- `package.json` - sedia untuk diterbitkan ke npm232233### Gunakan dalam JavaScript234235```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>244245 <script type="module">246 import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js";247248 let ctx;249 let imageData;250251 async function setup() {252 await init();253 const canvas = document.getElementById("canvas");254 ctx = canvas.getContext("2d");255256 // 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 }264265 window.applyGrayscale = () => {266 grayscale(imageData.data);267 ctx.putImageData(imageData, 0, 0);268 };269270 window.applyBrightness = () => {271 adjust_brightness(imageData.data, 1.3);272 ctx.putImageData(imageData, 0, 0);273 };274275 window.applyInvert = () => {276 invert(imageData.data);277 ctx.putImageData(imageData, 0, 0);278 };279280 setup();281 </script>282</body>283</html>284```285286Pandangan utama: `imageData.data` ialah `Uint8ClampedArray` yang disokong oleh `ArrayBuffer`. Apabila dihantar ke WASM, ia berkongsi memori yang sama - tiada penyalinan. Fungsi Rust mengubah suai piksel di tempat, dan pihak JavaScript melihat perubahan serta-merta.287288## Tahap Lebih Rendah: Instansiasi WASM Manual289290Jika anda tidak mahu menggunakan `wasm-bindgen`, anda boleh meng-instansiasikan modul WASM secara langsung:291292```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});300301// Call exported functions302const { add, multiply } = instance.exports;303console.log(add(5, 3)); // 8304console.log(multiply(4, 7)); // 28305```306307Ini berguna apabila anda mahukan overhead minimum dan tidak memerlukan interop jenis yang kaya.308309## Prestasi: WASM vs JavaScript310311Benchmark dunia nyata menunjukkan peningkatan kelajuan yang ketara untuk tugas intensif CPU:312313| Tugas | JavaScript | WASM | Peningkatan Kelajuan |314|------|-----------|------|---------|315| Pemprosesan imej 4K | 180ms | 8ms (dengan SIMD) | 22x |316| Ubah saiz imej (4K) | 250ms | 45ms | 5.5x |317| Simulasi fizik (10K entiti) | Menjatuhkan frame | 60fps lancar | ~10x |318| Parsing JSON (payload besar) | 12ms | 3ms | 4x |319| Hashing kriptografi | 45ms | 6ms | 7.5x |320321WASM berjalan pada kira-kira 95% kelajuan kod native. Keuntungan terbesar datang daripada:322- Prestasi yang boleh diramal (tiada pemanasan JIT, tiada jeda GC)323- Arahan SIMD untuk pemprosesan data selari324- Akses memori langsung tanpa gangguan garbage collector325326Di mana WASM TIDAK lebih pantas: manipulasi DOM, pengiraan kecil, tugas terikat I/O. JavaScript sudah dioptimumkan untuk ini.327328## Kes Penggunaan Pengeluaran329330### Figma: Rendering Vektor Masa Nyata331332Enjin rendering teras Figma ialah C++ yang dikompil ke WASM. Setiap bentuk, gradien, dan kesan dikira dalam WASM dan dilukis pada elemen Canvas. Ini membolehkan Figma mengendalikan reka bentuk kompleks dengan ribuan lapisan pada 60fps dalam pelayar - prestasi yang mustahil dalam JavaScript tulen.333334### Adobe Photoshop di Web335336Adobe memindahkan penapis dan alat Photoshop utama ke WASM menggunakan Rust. Benchmark mereka menunjukkan pemprosesan imej 4K dalam 22ms dengan WASM SIMD vs 180ms dalam JavaScript - peningkatan 8x yang membolehkan pratonton penapis masa nyata.337338### Cloudflare Workers339340Cloudflare menjalankan modul WASM dalam V8 isolates merentasi 330+ lokasi edge. Cold start ialah 1-5ms (berbanding 100-500ms untuk serverless berasaskan kontena). Pada Februari 2026, mereka menggunakan inferens Llama-3-8b merentasi rangkaian edge mereka menggunakan WASM.341342### Google Meet343344Kabur latar belakang dan latar belakang maya dalam Google Meet menggunakan WASM dengan SIMD untuk pemprosesan video masa nyata. Modul WASM memproses setiap frame video cukup pantas untuk mengekalkan video lancar pada 30fps.345346## Sokongan Pelayar (2026)347348| Ciri | Chrome | Firefox | Safari | Edge |349|---------|--------|---------|--------|------|350| Core WASM | Penuh | Penuh | Penuh | Penuh |351| Threads | Ya | Ya | Ya | Ya |352| SIMD (128-bit) | Ya | Ya | Ya | Ya |353| WasmGC | 119+ | 120+ | 18.2+ | Ya |354| Exception Handling | Ya | Ya | Ya | Ya |355| Memory64 | Ya | Ya | Separa | Ya |356357Semua pelayar utama menyokong WASM sepenuhnya. Ciri-ciri yang lebih baru (WasmGC, Exception Handling) telah mencapai ketersediaan yang luas.358359## Rujukan Tooling360361| Alat | Tujuan | Pasang |362|------|---------|---------|363| **wasm-pack** | Bina Rust ke WASM, hasilkan pakej npm | `cargo install wasm-pack` |364| **wasm-bindgen** | Binding interop Rust/JS (digunakan oleh wasm-pack) | Dependency dalam Cargo.toml |365| **wasm-opt** | Pengoptimuman saiz binari (pengurangan 50%+) | Sebahagian daripada Binaryen: `brew install binaryen` |366| **wit-bindgen** | Hasilkan binding daripada fail WIT | `cargo install wit-bindgen-cli` |367| **Wasmtime** | WASM runtime sisi pelayan (pelaksanaan rujukan WASI) | `brew install wasmtime` |368| **Wasmer** | WASM runtime alternatif dengan sokongan WASI | `curl https://get.wasmer.io -sSfL \| sh` |369| **wasm-feature-detect** | Pengesanan ciri pelayar pada runtime | `npm install wasm-feature-detect` |370371### Mengoptimumkan Saiz Binari372373Binari WASM boleh menjadi besar. Berikut cara mengecilkannya:374375```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```383384```bash385# Build in release mode386wasm-pack build --release --target web387388# Further optimize with wasm-opt389wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm390```391392Modul WASM Rust tipikal turun daripada 500KB kepada di bawah 50KB dengan pengoptimuman ini.393394## Peta Jalan Bermula395396```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]401402 A --> A1[Install Rust + wasm-pack]403 A --> A2[Build hello-world WASM module]404 A --> A3[Call WASM functions from JavaScript]405406 B --> B1[Build image processor or game physics]407 B --> B2[Use wasm-bindgen for rich types]408 B --> B3[Benchmark against pure JS]409410 C --> C1[Run WASM with Wasmtime]411 C --> C2[Explore WASI interfaces]412 C --> C3[Try Component Model with WIT]413414 D --> D1[Optimize binary size]415 D --> D2[Use SIMD for parallelism]416 D --> D3[Deploy to Cloudflare Workers or browser]417```418419## Kesimpulan420421WebAssembly tidak lagi eksperimental. Ia adalah teknologi pengeluaran yang digunakan oleh beberapa aplikasi paling mencabar di web. Prestasi hampir native, keselamatan sandboxed, dan kemudahalihan universal - tiada sasaran kompilasi lain memberi anda ketiga-tiganya.422423Anda tidak perlu menulis semula seluruh aplikasi anda dalam WASM. Mulakan dengan satu fungsi intensif CPU - penapis imej, parser data, pengiraan fizik - kompilkannya ke WASM, dan panggilnya daripada JavaScript. Ukur perbezaannya. Kemudian tentukan di mana lagi WASM boleh membantu.424425Tooling sudah matang, sokongan pelayar universal, dan ekosistem berkembang. Jika anda menulis Rust, anda sudah satu arahan daripada pelayar.426427> **Senarai Semak Bermula:**428>429> - [x] Rust dan wasm-pack dipasang430> - [x] Modul WASM pertama dibina dan berjalan dalam pelayar431> - [x] Interop JavaScript berfungsi (memanggil WASM daripada JS)432> - [x] Release build dengan pengoptimuman saiz digunakan433> - [x] Prestasi dibandingkan dengan kesetaraan JavaScript tulen434> - [x] WASI diterokai dengan Wasmtime untuk kes penggunaan sisi pelayan435
:WebAssembly untuk Pembangun Web: Dari Kosong ke Pengeluaranlines 1-435 (END) — press q to close