Ukratko

Najvažnije iz članka

  • WebAssembly (Wasm) je binarni format instrukcija koji omogućuje izvršavanje koda blizu izvorne brzine u web pregledniku.
  • Wasm nije zamjena za JavaScript, već njegov komplement, idealan za performanse kritične zadatke (npr. igre, obrada multimedije, strojno učenje).
  • Jezici poput C, C++, Rust kompiliraju se u `.wasm` datoteke, koje se zatim učitavaju i instanciraju unutar JavaScript aplikacije, omogućujući dvosmjernu komunikaciju.
  • Rust je popularan izbor za Wasm razvoj zbog sigurnosti memorije i odličnih alata poput `wasm-bindgen`, koji olakšava integraciju s JavaScriptom.
Sadržaj članka
  1. Što je WebAssembly i zašto je važan?
  2. Kako WebAssembly funkcionira?
  3. Praktični Primjer: Korištenje Rusta za Wasm modul
  4. Naprednije Korištenje i Razmatranja
  5. Kada koristiti WebAssembly?
  6. Budućnost WebAssemblyja
  7. Zaključak

Internet je desetljećima evoluirao od statičkih HTML stranica do dinamičnih, interaktivnih web aplikacija koje konkuriraju izvornim desktop aplikacijama. JavaScript je bio i još uvijek jest srce ove revolucije, omogućujući složenu logiku i korisnička sučelja izravno u pregledniku. Međutim, s rastućim zahtjevima za performansama, pogotovo u domenama kao što su igre, obrada multimedije, strojno učenje u pregledniku i kompleksne znanstvene vizualizacije, ograničenja JavaScripta postaju sve očitija. Tu na scenu stupa WebAssembly (Wasm) – binarni format instrukcija za virtualni stroj baziran na stogovima. Wasm je osmišljen kao portabilna meta kompilacije za programske jezike visokog nivoa poput C, C++, Rust, a u novije vrijeme i Go, C# te mnoge druge, omogućujući njihovo izvršavanje na webu s performansama bliskim izvornim.

Što je WebAssembly i zašto je važan?

WebAssembly nije zamjena za JavaScript, već njegov komplement. Zamislite ga kao moćnog suvozača koji preuzima teške zadatke, dok JavaScript i dalje orkestrira cjelokupan rad aplikacije. Ključne prednosti Wasm-a uključuju:

  • Performanse: Wasm kod se izvršava mnogo brže od JavaScripta jer je unaprijed preveden u binarni format koji preglednici mogu optimizirati i izvršiti gotovo kao izvorni kod. To eliminira mnoge troškove povezane s JIT (Just-In-Time) kompilacijom JavaScripta.
  • Predvidljivost performansi: Za razliku od JavaScripta, čije performanse mogu varirati ovisno o JIT optimizacijama, Wasm nudi stabilnije i predvidljivije performanse. Ovo je ključno za aplikacije osjetljive na latenciju.
  • Sigurnost: Wasm se izvršava u sigurnom "sandbox" okruženju preglednika, slično JavaScriptu, što znači da ne može izravno pristupiti resursima sustava. Ovo osigurava da je kod siguran za izvršavanje na bilo kojem uređaju.
  • Portabilnost: Wasm je dizajniran da bude neovisan o platformi i pregledniku. Jednom preveden u Wasm, kod radi jednako na svim modernim preglednicima koji ga podržavaju.
  • Korištenje postojećeg koda: Omogućuje developerima da iskoriste ogromnu količinu postojećeg koda napisanog u jezicima poput C/C++ i Rusta, prenoseći ga na web bez potpunog prepisivanja. Ovo otvara vrata novim kategorijama web aplikacija.

Kako WebAssembly funkcionira?

Proces korištenja WebAssemblyja obično uključuje sljedeće korake:

  1. Odabir izvornog jezika: Odaberete jezik u kojem ćete pisati kod koji želite ubrzati (npr. C, C++, Rust).
  2. Kompilacija u Wasm: Posebni alati i kompilatori (kao što su Emscripten za C/C++ ili wasm-bindgen za Rust) prevode vaš izvorni kod u .wasm binarnu datoteku. Ovi alati također generiraju JavaScript "glue" kod koji olakšava interakciju između vaše Wasm instance i ostatka vaše JavaScript aplikacije.
  3. Učitavanje i instanciranje: Vaša JavaScript aplikacija učitava .wasm datoteku, a zatim je instancira. Instanciranjem se kreira WebAssembly modul koji se može koristiti kao običan JavaScript objekt.
  4. Interakcija: JavaScript može pozivati funkcije definirane unutar Wasm modula, prosljeđivati im argumente i primati rezultate. Slično tome, Wasm kod može pozivati JavaScript funkcije (iako je to nešto složeniji proces, često se koristi za pristup DOM-u ili Web API-jima).

Memorija u Wasm-u: Wasm operira na linearnoj memoriji, što je niz bajtova. Ovaj memorijski prostor je izoliran od JavaScript memorije i Wasm ga može izravno manipulirati. JavaScript može čitati i pisati u taj isti memorijski prostor putem WebAssembly.Memory objekta, koristeći tipizirane polja (Typed Arrays) za efikasan pristup.

Praktični Primjer: Korištenje Rusta za Wasm modul

Za frontend developere koji žele započeti s Wasm-om, Rust je odličan izbor. Njegov naglasak na sigurnosti memorije, performanse i izvrsna podrška za WebAssembly čine ga idealnim kandidatom. Pokazat ćemo vam jednostavan primjer kako stvoriti Wasm modul u Rustu i integrirati ga s JavaScriptom.

Preduvjeti:

  • Rustup: Alat za upravljanje verzijama Rusta. Instalirajte ga s curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh.
  • wasm-pack: Alat koji olakšava izgradnju i pakiranje Rust koda za WebAssembly. Instalirajte ga s cargo install wasm-pack.

Korak 1: Stvaranje Rust projekta

cargo new --lib wasm_calculator
cd wasm_calculator

Korak 2: Dodavanje ovisnosti i konfiguracija za Wasm

U Cargo.toml dodajte:

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

cdylib (C Dynamic Library) je tip knjižnice koji je pogodan za generiranje Wasm modula. wasm-bindgen je ključan za premošćivanje Rust i JavaScript svijeta, omogućujući pozivanje Rust funkcija iz JS-a i obratno.

Korak 3: Pisanje Rust koda

U src/lib.rs implementirat ćemo jednostavnu funkciju zbrajanja:

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

// Dodatno: Funkcija koja demonstrira logiranje u konzolu iz Rusta
#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[wasm_bindgen]
pub fn greet(name: &str) {
    log(&format!("Hello, {} from Rust!", name));
}

Atribut #[wasm_bindgen] iznad funkcije add označava da ta funkcija treba biti dostupna JavaScriptu. extern "C" { ... } blok omogućuje Rust kodu da poziva JavaScript funkcije, u ovom slučaju console.log.

Korak 4: Kompilacija u Wasm

Iz terminala u korijenskom direktoriju wasm_calculator pokrenite:

wasm-pack build --target web

Ova naredba će stvoriti direktorij pkg koji sadrži:

  • wasm_calculator_bg.wasm: Binarni Wasm modul.
  • wasm_calculator.js: JavaScript "glue" kod za interakciju s Wasm modulom.
  • TypeScript definicije (.d.ts) ako koristite TypeScript.

Opcija --target web generira JS modul optimiziran za izravnu upotrebu u preglednicima (bez bundlera). Za bundlere poput Webpacka, Parcel-a ili Rollup-a koristite --target bundler.

Korak 5: Integracija s JavaScriptom (Frontend)

Kreirajte index.html i index.js u korijenskom direktoriju projekta (ili unutar nekog drugog frontend projekta):

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Wasm Calculator</title>
</head>
<body>
    <h1>Wasm Calculator Example</h1>
    <p>Result of 5 + 3 from Wasm: <span id="result"></span></p>
    <script type="module" src=""./index.js"></script>"
</body>
</html>

index.js:

import init, { add, greet } from './pkg/wasm_calculator.js';

async function run() {
    // Inicijalizira Wasm modul. Potrebno je pozvati prije korištenja bilo koje Wasm funkcije.
    await init();

    const num1 = 5;
    const num2 = 3;
    const sum = add(num1, num2);

    document.getElementById('result').textContent = sum;

    greet("Bajter"); // Poziva Rust funkciju koja logira u konzolu

    console.log(`Add function from Wasm: ${num1} + ${num2} = ${sum}`);
}

run();

Pokrenite jednostavan HTTP server u direktoriju projekta (npr. npx http-server ili python -m http.server) i otvorite index.html u pregledniku. Vidjet ćete rezultat zbrajanja i poruku u konzoli.

Naprednije Korištenje i Razmatranja

Rad s Podacima (Stringovi, Složeni Objekti)

Prosljeđivanje primitivnih tipova (brojevi) između JavaScripta i Wasm-a je jednostavno. Međutim, za složenije strukture poput stringova ili objekata, potrebna je pažljivija manipulacija memorijom. wasm-bindgen automatizira veći dio toga, ali je korisno razumjeti osnovni princip:

  • Stringovi: Stringovi se prosljeđuju kao pokazivači na memoriju Wasm-a i njihova duljina. Rust knjižnice poput wasm_bindgen transparentno upravljaju konverzijom između JavaScriptovih UTF-8 stringova i Rustovih String ili &str tipova.
  • Složeni Objekti: Za složene objekte, često se koristi serializacija/deserializacija (npr. JSON). Objekt se u JavaScriptu pretvara u JSON string, prosljeđuje Wasm-u (kao string), tamo se parsira, obrađuje i rezultat se vraća natrag na sličan način.

Multithreading (Web Workers i SharedArrayBuffer)

WebAssembly se, u kombinaciji s Web Workers i SharedArrayBuffer (koji omogućuje dijeljenu memoriju između threadova), može koristiti za implementaciju multithreadinga. Ovo je posebno moćno za paralelno izvršavanje intenzivnih operacija, otključavajući puni potencijal modernih višejezgrenih procesora unutar preglednika.

Integracija s Frontend Frameworksima

Wasm moduli se bez problema integriraju s popularnim frontend frameworkovima kao što su React, Vue ili Angular. Jednostavno ih uvozite i koristite kao bilo koji drugi JavaScript modul. Bundleri poput Webpacka imaju podršku za Wasm, automatski ga tretirajući kao ovisnost.

Debugging Wasm koda

Moderni preglednici, poput Chromea i Firefoxa, imaju sve bolju podršku za debugging WebAssemblyja. Možete postavljati breakpointove direktno unutar Rust ili C++ izvornog koda (ako je generiran s debug informacijama), pregledavati memoriju i stack trace.

WebAssembly System Interface (WASI)

Dok je Wasm izvorno dizajniran za preglednike, WASI (WebAssembly System Interface) proširuje njegovu primjenu na serversko okruženje i druge runtime okoline izvan preglednika. WASI definira skup standardiziranih API-ja za interakciju s operativnim sustavom (datotečni sustav, mreža, varijable okoline), čineći Wasm istinski univerzalnom platformom za prijenosni i siguran kod, čak i na serveru ili IoT uređajima.

Kada koristiti WebAssembly?

Iako je WebAssembly moćan, nije zamjena za JavaScript za sve scenarije. Evo kada ga je najpametnije koristiti:

  • Performanse kritične operacije: Numeričke simulacije, video i audio obrada, enkripcija/dekripcija, kompresija podataka, složeni algoritmi.
  • Igre: Izvršavanje enginea igara ili kompleksne fizike izravno u pregledniku.
  • Emulacija: Emulacija starijih sustava ili specifičnog hardvera.
  • Strojno učenje/AI: Izvršavanje pretreniranih modela ili inferencija na strani klijenta.
  • Ponovna upotreba koda: Kada imate veliku bazu koda u C/C++/Rust koju želite donijeti na web bez prepisivanja.
  • Biblioteke niskog nivoa: Implementacija specifičnih algoritama koji zahtijevaju finu kontrolu nad memorijom i CPU-om.

Za većinu UI interakcija, DOM manipulaciju, mrežne zahtjeve i opću logiku aplikacije, JavaScript ostaje bolji i jednostavniji izbor.

Budućnost WebAssemblyja

Budućnost WebAssemblyja izgleda vrlo svijetla. Razvoj je aktivan, s novim prijedlozima i značajkama koje se stalno dodaju. Neke od nadolazećih značajki uključuju:

  • Garbage Collection (GC): Omogućit će jezicima s vlastitim GC-om (poput Jave ili C#) da efikasnije ciljaju Wasm, smanjujući veličinu modula i poboljšavajući performanse.
  • Reference Types: Omogućit će Wasm-u izravnu interakciju s JavaScript objektima, smanjujući potrebu za serijalizacijom.
  • Component Model: Vizija za modularni ekosustav gdje se Wasm moduli mogu kombinirati i ponovno koristiti s minimalnim naporom, neovisno o izvornom jeziku.
  • SIMD (Single Instruction, Multiple Data): Dodatne instrukcije za paralelnu obradu podataka, što je ključno za multimediju i znanstveno računarstvo.

Ove značajke dodatno će proširiti moć i primjenjivost WebAssemblyja, čineći ga još nezaobilaznijim alatom u arsenalu frontend developera, ali i developera općenito.

Zaključak

WebAssembly predstavlja značajan korak naprijed u evoluciji web platforme. Omogućava izvršavanje visokoperformansnog koda u pregledniku s razinom učinkovitosti koja je do sada bila nezamisliva. Za frontend developere, ovo otvara vrata za stvaranje bogatijih, kompleksnijih i bržih web aplikacija, premostivši jaz između web i nativnih aplikacija. Razumijevanje i korištenje WebAssemblyja postat će sve važnije kako se web platforma nastavlja razvijati, nudeći nam alate za izgradnju budućnosti weba. Iako zahtijeva početno ulaganje u učenje novih jezika i alata, povrat na to ulaganje u obliku performansi i mogućnosti može biti golem. Prihvatite WebAssembly i otključajte novi potencijal za vaše web projekte!

Izvori i dodatno čitanje

  1. WebAssembly.org - Službena stranica
  2. MDN Web Docs - WebAssembly
  3. The Rust and WebAssembly Book
  4. WASI (WebAssembly System Interface) Overview
B
Uredništvo portala

BAJT

Službeni autorski profil redakcije portala BAJT. Sadržaj priprema i provjerava uredništvo portala.