WebAssembly ile Modern Web Geliştirme: JavaScript'in Ötesinde
WebAssembly'in web platformunu nasıl dönüştürdüğü — yüksek performanslı tarayıcı uygulamalarından sunucusuz bilişime. Geliştiriciler için pratik bir rehber.
JavaScript, yirmi yılı aşkın süredir web'in tartışmasız tek dili konumundaydı, ancak tarayıcı çalışma zamanı artık tek dilli bir ortam değil. WebAssembly, sessizce her modern tarayıcıda ikinci çalışma zamanı haline geldi ve JavaScript'in tek başına verimli bir şekilde sunamayacağı yetenekleri mümkün kılıyor. Görüntü düzenleyiciler, video codec'leri, veritabanı motorları, 3D işleyiciler, dil çalışma zamanları — bunların hepsi bugün tarayıcı sekmelerinin içinde, neredeyse yerel hızda çalışan düşük seviyeli bir ikili formata derlenmiş olarak çalışıyor.
WebAssembly nedir ve neden önemlidir
WebAssembly, yığın tabanlı bir sanal makinede çalışan düşük seviyeli bir ikili komut formatıdır. Programlama dilleri için taşınabilir bir derleme hedefi olarak tasarlanmış olup, istemci ve sunucu uygulamaları için web'de dağıtımı mümkün kılar. Dört büyük tarayıcı satıcısı — Google, Mozilla, Apple ve Microsoft — tasarımında işbirliği yaptı ve 2019'da bir W3C standardı haline geldi. Her büyük tarayıcı 2017'den beri desteğini sunuyor.
Ancak WebAssembly, JavaScript'in yerine geçmek için tasarlanmadı. Onu tamamlayıcı bir teknolojidir. JavaScript, DOM manipülasyonu, olay yönetimi ve UI mantığının dili olmaya devam ediyor. WebAssembly ise JavaScript'in asla tasarlanmadığı hesaplama yoğunluklu işleri üstleniyor. İki çalışma zamanı aynı sekmede birlikte çalışıyor; modüller JavaScript fonksiyonlarını içe aktarırken, JavaScript de iyi tanımlanmış bir API aracılığıyla Wasm dışa aktarımlarını çağırıyor.
WebAssembly, JavaScript'in yerini almayı hedeflemez. Amacı, JavaScript'in verimli bir şekilde çözemeyeceği sorunları çözmektir. Geliştiriciler aynı uygulama içinde her iş için doğru aracı seçebildiğinde web platformu daha güçlü hale gelir.
Wasm temelleri: ikili format ve doğrusal bellek
WebAssembly modülleri, hızlı ayrıştırma ve küçük aktarım boyutu için tasarlanmış bir ikili format (.wasm dosyaları) kullanır. Format oldukça derli topludur — tipik bir modül, küçültme sonrasında bile eşdeğer JavaScript'ten önemli ölçüde daha küçüktür. İkili format; türleri, fonksiyonları, içe aktarımları, dışa aktarımları, bellek bildirimlerini ve talimatları, tarayıcıların tek bir doğrusal geçişte doğrulayıp derleyebileceği yoğun bir temsilde kodlar.
Her WebAssembly modülü, kavramsal bir yığın makinesi üzerinde çalışır. Talimatlar, değerleri bir değerlendirme yığınına iter ve işlemleri gerçekleştirmek için değerleri yığından çıkarır. Desteklenen değer türleri i32, i64, f32 ve f64'tür — 32-bit ve 64-bit tamsayılar ile kayan noktalı sayılar. Wasm seviyesinde string, nesne, dizi veya başka herhangi bir yüksek seviyeli tür bulunmaz. Tüm karmaşık veri yapıları, doğrusal bellekte ham baytlar olarak temsil edilmelidir.
Doğrusal bellek, WebAssembly'deki en önemli kavramdır. Her modül, bitişik ve yeniden boyutlandırılabilir bir veya daha fazla bellek bloğu bildirebilir. Bu bellek, modülün yükleme ve depolama talimatlarını kullanarak okuyup yazdığı düz bir bayt dizisidir. Ana bilgisayar (JavaScript çalışma zamanı veya Wasm çalışma zamanı) başlangıç boyutunu ve maksimum boyutu kontrol eder ve her biri 65.536 baytlık ek sayfalar talep ederek belleği büyütebilir. Ana bilgisayar tarafından bu bellek bir ArrayBuffer olarak erişilebilirdir; bu da JavaScript'in Wasm modülünün kullandığı belleği okuyup yazabileceği anlamına gelir.
Bu paylaşımlı bellek modeli, WebAssembly'i verimli kılan şeydir. Ana bilgisayar ve modül, serileştirme veya kopyalama olmadan veri alışverişi yapabilir — aynı arabelleğe yazıp okurlar. Bir Rust fonksiyonu JavaScript'e bir string döndürdüğünde, string baytlarını doğrusal belleğe yazar ve bir işaretçi (bir tamsayı ofseti) ile bir uzunluk döndürür. JavaScript bu baytları doğrudan ArrayBuffer'dan okur. JSON ayrıştırma, mesaj geçirme veya fonksiyon çağrısının ötesinde herhangi bir ek yük yoktur.
Modül yapısı ve doğrulama
Bir WebAssembly modülü bölümlerden oluşur: tür bölümü fonksiyon imzalarını tanımlar, fonksiyon bölümü fonksiyonları bildirir, kod bölümü asıl bayt kodunu içerir, bellek bölümü doğrusal belleği tanımlar ve dışa aktarım bölümü fonksiyonları ve belleği ana bilgisayara sunar. Herhangi bir modül çalıştırılmadan önce, tarayıcı onu yapısal olarak doğrular ve tür güvenliğini zorunlu kılar. Doğrulama, tüm talimat işlenenlerinin beklenen türleriyle eşleşmesini, tüm fonksiyon çağrılarının geçerli imzalara başvurmasını ve tüm bellek erişimlerinin bildirilen sınırlar içinde kalmasını garanti eder. Bu doğrulama milisaniyeler içinde gerçekleşir ve hatalı biçimlendirilmiş bir modülün çalışma zamanını istismar edemeyeceğini garanti eder.
Güvenlik modeli açık ve kısıtlıdır. Bir WebAssembly modülü, ana bilgisayar bu yetenekleri içe aktarılan fonksiyonlar aracılığıyla açıkça sağlamadıkça DOM'a erişemez, ağ istekleri yapamaz, dosya okuyamaz veya herhangi bir sistem etkileşimi gerçekleştiremez. Modül, doğrusal belleğinin ve içe aktarılan fonksiyon tablosunun dışında hiçbir şeye erişimi olmayan bir kum havuzunda çalışır. Bu, WebAssembly modüllerini güvenilmeyen kaynaklardan çalıştırmak için güvenli kılar — bu özellik hem tarayıcı hem de sunucu tarafı Wasm için kritiktir.
Wasm'a derleme: Rust, C, Go, Zig karşılaştırması
WebAssembly derleme hedefinin kalitesi dile göre önemli ölçüde değişir. Bazı diller, minimum ek yük ile sıkı ve verimli Wasm modülleri üretir. Diğerleri, ikili boyuta megabaytlar ekleyen bir çalışma zamanı gerektirir. Wasm projeniz için doğru kaynak dilini seçmek, performans gereksinimlerinize, ekibinizin uzmanlığına ve ihtiyacınız olan entegrasyonun karmaşıklığına bağlıdır.
Rust: Wasm için altın standart
Rust, herhangi bir dil arasında en iyi WebAssembly desteğine sahiptir. wasm-pack araç zinciri, derleme, optimizasyon ve JavaScript bağlayıcı kod üretimini sorunsuz bir şekilde halleder. Rust, küçük Wasm ikili dosyaları üretir çünkü çöp toplayıcısı, ağır bir çalışma zamanı yoktur ve sahiplik modeli doğal olarak doğrusal bellek yönetimine uyum sağlar. Birkaç dışa aktarılan fonksiyona sahip tipik bir Rust Wasm modülü, LTO ve optimizasyon sonrasında 10 KB ile 50 KB arasındadır ve bu, elle yazılmış Wasm ile rekabet edebilir düzeydedir.
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {}! Wasm says hello.", name)
}wasm_bindgen kütüphanesi, doğrusal bellek yönetimini otomatik olarak halleden JavaScript yapıştırıcı kodu üretir. JavaScript'ten fibonacci'yi çağırmak, diğer herhangi bir JavaScript fonksiyonunu çağırmak gibi görünür ve hissettirir. Arka planda wasm_bindgen, string parametrelerini işaretçi-uzunluk çiftlerine dönüştürür, Wasm fonksiyonunu çağırır ve sonucu bir JavaScript string'ine geri çevirir. Bu soyutlama katmanı minimum ek yük ekler ve Rust-Wasm entegrasyonunu günlük kullanım için pratik hale getirir.
Emscripten ile C ve C++
Emscripten, orijinal Wasm derleme araç zinciridir. LLVM'yi arka uç olarak kullanarak C ve C++ kodunu Wasm'a derler ve mevcut yerel uygulamaları minimum kaynak değişikliğiyle web'e taşımayı mümkün kılan kapsamlı bir POSIX uyumluluk katmanı sağlar. Emscripten; sanal bir dosya sistemi, OpenGL'den WebGL'ye çeviri, pthread öykünmesi ve modül yaşam döngüsünü yöneten bir JavaScript çalışma zamanı içerir.
Resmi Wasm arka ucu ile Go
Go, Go 1.11 ile WebAssembly desteği ekledi ve her sürümle birlikte iyileşmeye devam ediyor. Bir Go programını Wasm'a derlemek oldukça basittir — GOOS=js GOARCH=wasm ortam değişkenlerini ayarlayıp go build komutunu çalıştırırsınız. Ancak Go'nun Wasm desteği, Rust'a kıyasla önemli sınırlamalara sahiptir. Go, her Wasm ikili dosyasında kendi çalışma zamanını (goroutine zamanlayıcı, çöp toplayıcı, defer yığını) içerir; bu da minimal bir Go Wasm modülünün yaklaşık 2 MB'tan başlaması anlamına gelir. Bu, ikili dosya boyutunun daha az önemli olduğu sunucu tarafı Wasm için kabul edilebilir olsa da, indirme ve ayrıştırma süresinin kritik olduğu tarayıcı kullanım durumları için engelleyicidir.
Zig: yeni rakip
Zig, birinci sınıf WebAssembly desteği ile C'nin modern bir alternatifi olarak konumlanıyor. Zig derleyicisi, Emscripten gibi herhangi bir araç zinciri sarmalayıcısı olmadan doğrudan Wasm hedefleyebilir. Zig, boyut ve performans açısından Rust ile rekabet edebilecek Wasm modülleri üretir ve comptime özelliği, çalışma zamanı ek yükünü tamamen ortadan kaldırabilen meta programlamayı mümkün kılar. Zig, açıkça bağlamadığınız sürece gizli bir çalışma zamanı — çöp toplayıcı, bellek ayırıcı, başlangıç kodu — içermez.
- Rust, en küçük Wasm ikili dosyalarını (tipik modüller için 10-50 KB) üretir ve wasm-pack ile wasm-bindgen ile en iyi araç ekosistemine sahiptir.
- Emscripten ile C ve C++, mevcut yerel kod tabanlarını Wasm'a taşımak için en iyi seçenektir; en yüksek uyumluluğa sahiptir ancak daha büyük ikili dosya boyutları üretir.
- Go, Wasm'a kolayca derlenir ancak dahil edilen çalışma zamanı nedeniyle büyük ikili dosyalar (2 MB+) üretir; bu da onu sunucu tarafı Wasm için daha uygun kılar.
- Zig, çalışma zamanı ek yükü olmayan sıkı Wasm modülleri üretir ve minimum gömülü Wasm kullanım durumları için idealdir.
Tarayıcıda Wasm kullanımı
Bir WebAssembly modülünü tarayıcıda yüklemek ve çalıştırmak, tüm modern tarayıcılarda tutarlı olan standart bir API'yi izler. WebAssembly JavaScript API'si, compile, instantiate ve instantiateStreaming fonksiyonlarıyla WebAssembly ad alanını sağlar. Akış varyantı tercih edilir çünkü modülü baytlar indirilirken derlemeye başlar ve ağ G/Ç'sini derleme ile üst üste bindirir.
async function loadWasm(url: string) {
const response = await fetch(url);
const results = await WebAssembly.instantiateStreaming(response);
return results.instance.exports;
}
async function main() {
const wasm = await loadWasm("/fibonacci.wasm");
console.log(wasm.fibonacci(40));
}
main().catch(console.error);instantiateStreaming API'si, bir instance özelliği (derlenmiş modül örneği) ve Wasm modülünde dışa aktarım olarak bildirilen tüm fonksiyonları ve belleği içeren bir exports nesnesi döndürür. İkinci argüman olarak bir imports nesnesi de iletebilirsiniz; bu, modüle derlenirken beklediği JavaScript fonksiyonlarına ve değerlerine erişim sağlar.
Üretim kullanımı için, Wasm modülünü derleme adımı sırasında önceden derlemek veya bir paketleyici eklentisi kullanmak istersiniz. Webpack 5, Wasm içe aktarımlarını yerel olarak destekler ve Vite deneysel Wasm desteğine sahiptir. Bu paketleyiciler fetch, örnekleme ve yaşam döngüsü yönetimini otomatik olarak halleder; Wasm modüllerini JavaScript modülleriymiş gibi içe aktarmanıza olanak tanır. wasm-pack kullanıldığında içe aktarma deseni import init from './pkg/fibonacci.js' şeklinde görünür ve size tüm yapıştırıcı kodu yöneten promise tabanlı bir başlatma fonksiyonu verir.
Tarayıcı Wasm için kritik bir husus, ilk derleme aşamasıdır. Wasm modülleri, ilk yüklemede ikili formatlarından yerel koda derlenir. Küçük modüller için derleme birkaç milisaniye sürer. 10 MB'ın üzerindeki büyük modüller için derleme birkaç yüz milisaniye sürebilir ve ana iş parçacığını bloke edebilir. Çözüm, WebAssembly.compileStreaming'i bir Web Worker içinde kullanmaktır; bu, modülü ana iş parçacığının dışında derler ve ana iş parçacığının anında örnekleyebileceği derlenmiş bir modül nesnesi döndürür. Bu desen, büyük Wasm modülleri yükleyen üretim uygulamaları için gereklidir.
WASI ve sunucu tarafı Wasm
WebAssembly başlangıçta yalnızca tarayıcı için tasarlanmıştı, ancak güvenlik modeli ve performans özellikleri onu sunucu tarafı kullanım durumları için de eşit derecede cazip kılıyor. Zorluk, tarayıcının sunucu tarafı ortamlarında bulunmayan belirli ana bilgisayar API'leri — DOM, fetch, WebSocket — sağlamasıdır. WebAssembly System Interface, Wasm modüllerinin tarayıcı dışında kullanabileceği standart bir POSIX benzeri sistem çağrıları kümesi tanımlayarak bu sorunu çözer.
WASI; dosya G/Ç'si, ağ iletişimi, saat erişimi, rastgele sayı üretimi, ortam değişkenleri ve komut satırı argümanı yönetimi için soyutlamalar sağlar. WASI desteğiyle derlenmiş bir Wasm modülü, herhangi bir WASI uyumlu çalışma zamanında çalışan standartlaştırılmış bir arayüz aracılığıyla dosyaları okuyabilir, ağ soketleri açabilir ve işletim sistemiyle etkileşime girebilir. Bu, Wasm'i bir sunucu uygulaması olarak çalıştırmanın temelidir.
WASI standardı birden çok anlık görüntü aracılığıyla gelişmektedir. WASI preview 1, çoğu araç zincirinin bugün desteklediği kararlı temel seviyedir. WASI preview 2, her Wasm modülünün hangi sistem kaynaklarına ihtiyaç duyduğunu açıkça bildirdiği, yetenek tabanlı güvenlik ile bileşen modeli bilincine sahip bir tasarım sunar. Preview 2, önemli bir mimari iyileştirmedir çünkü ince taneli izin modellerini mümkün kılar — yalnızca belirli bir dosyayı okuması gereken bir modül, sistemdeki başka hiçbir dosyaya erişemez.
WASI, WebAssembly'i bir tarayıcı teknolojisinden evrensel bir kum havuzlu çalışma zamanına dönüştürüyor. Bir tarayıcı sekmesinde çalışan aynı modül, değişiklik yapılmadan bir sunucu tarafı Wasm çalışma zamanında, bir sunucusuz fonksiyonda veya bir uç düğümde de çalışabilir. Bir kere yaz, her yerde çalıştır, bu her yere JavaScript'in ulaşamadığı ortamlar da dahil olduğunda yeni bir anlam kazanıyor.
Wasm çalışma zamanları ve dağıtım
WebAssembly'i tarayıcı dışında çalıştırmak bir sunucu tarafı Wasm çalışma zamanı gerektirir. Her biri farklı tasarım felsefelerine ve kullanım durumlarına sahip birkaç olgun çalışma zamanı mevcuttur. En önemli üç tanesi Wasmtime, Wasmer ve gömülü sistemler için WAMR'dir (WebAssembly Micro Runtime).
Wasmtime
Wasmtime, WASI standardını yönlendiren aynı kuruluş olan Bytecode Alliance tarafından geliştirilen bağımsız bir Wasm çalışma zamanıdır. Rust ile yazılmıştır, Wasm modüllerini Cranelift (özellikle Wasm için tasarlanmış bir kod üreticisi) kullanarak derler ve Rust, C, Python ve diğer dillerde API'ler sağlar. Wasmtime, sunucu tarafı Wasm için en yaygın kullanılan çalışma zamanıdır ve Cloudflare Workers, Fastly Compute@Edge ve diğer birçok uç bilişim platformunun arkasındaki çalışma zamanıdır.
use wasmtime::*;
fn main() -> Result<()> {
let engine = Engine::default();
let module = Module::from_file(&engine, "hello.wasm")?;
let mut store = Store::new(&engine, ());
let instance = Instance::new(&mut store, &module, &[])?;
let hello = instance
.get_typed_func::<(), ()>(&mut store, "hello")?;
hello.call(&mut store, ())?;
Ok(())
}Wasmtime'ın gömme API'si temiz ve doğaldır. Bir Engine (derleme ortamı) oluşturur, bir dosyadan veya baytlardan Module yükler, bir Store (Wasm doğrusal belleğini tutan yürütme bağlamı) oluşturur ve dışa aktarılan fonksiyonlarına erişmek için modülü örneklersiniz. Çalışma zamanı, bellek yönetimini, tuzak işlemeyi ve WASI sistem çağrısı yönlendirmeyi otomatik olarak halleder.
Wasmer
Wasmer, birden çok derleme arka ucu — Cranelift, LLVM ve Singlepass (minimum optimizasyonla hızlı JIT derleme için) — destekleyen bir başka popüler Wasm çalışma zamanıdır. Wasmer; Rust, C, C++, Python, Go, PHP, Ruby, Java ve diğerleri için dil SDK'ları sağlayarak neredeyse her programlama ortamından erişilebilir olmasını sağlar. Wasmer ayrıca, npm'e benzer şekilde ancak Wasm modülleri için, Wasm modüllerini dağıtmak üzere bir paket kaydı (WAPM) sunar.
Wasmer ve Wasmtime arasındaki temel fark, Wasmer'in geliştirici deneyimi ve gömme kolaylığına odaklanması, Wasmtime'ın ise standartlara uygunluk ve güvenliğe odaklanmasıdır. Her ikisi de mükemmel seçimlerdir ve seçiminiz, çalışma zamanı ekosistem çeşitliliğine (Wasmer) mi yoksa katı spesifikasyon uyumluluğu ve üretim geçmişine (Wasmtime) mı değer verdiğinize bağlıdır.
- Wasmtime: Üretim sunucu tarafı Wasm için en iyisi, sıkı WASI uyumluluğu, Cranelift JIT derleyicisi, Cloudflare ve Fastly tarafından kullanılır.
- Wasmer: Wasm'i Rust dışındaki uygulamalara gömmek için en iyisi, neredeyse yerel hız için LLVM derlemesini destekler, WAPM paket ekosistemine sahiptir.
- WAMR: IoT ve gömülü cihazlar için en iyisi, küçük boyutlu, yorumlayıcı ve JIT modları, iwasm CLI aracını destekler.
Performans özellikleri ve Wasm'in ne zaman kazandığı
WebAssembly'in JavaScript'e karşı performans avantajı iş yüküne bağlıdır. CPU yoğunluklu, sayısal ağırlıklı işlemlerde Wasm tipik olarak JavaScript'ten 1,5 ila 3 kat daha hızlı çalışır. Görüntü işleme veya veri sıkıştırma gibi bellek yoğunluklu işlemlerde avantaj daha büyük olabilir çünkü Wasm, bellek düzeni ve ayırma desenleri üzerinde doğrudan kontrole sahiptir. G/Ç yoğunluklu veya DOM ağırlıklı iş yüklerinde Wasm'in bir avantajı yoktur ve Wasm modülü ile JavaScript ana bilgisayarı arasındaki köprüleme maliyeti nedeniyle ek yük ekleyebilir.
Derleme modeli başka bir faktördür. JavaScript, JIT derlemesi kullanır; kodu hemen çalıştırmaya başlar ancak sık kullanılan yolları zamanla optimize eder. Wasm, önceden veya modül yükleme zamanında derlenir, bu nedenle en yüksek performansa hemen ulaşır — hiçbir ısınma süresi yoktur. Kısa ömürlü fonksiyonlar veya tek seferlik çalıştırmalar için bu, JavaScript'i ilk çağrıda yavaşlatabilen JIT ısınma gecikmesini ortadan kaldırır.
Öngörülebilirlik, Wasm'in gerçekten parladığı alandır. JavaScript JIT optimizasyonu belirleyici değildir — aynı fonksiyon, aldığı türlere, kaç kez çağrıldığına ve JIT derleyicisinin o anki durumuna bağlı olarak optimize edilebilir veya optimizasyonu geri alınabilir. Wasm yürütmesi belirleyicidir. Her talimatın sabit bir maliyeti vardır. Çöp toplama duraklaması, tür karışıklığı veya optimizasyon iptali yoktur. Bu, Wasm'i gecikme tutarlılığının teorik en yüksek verimden daha önemli olduğu iş yükleri için doğru seçim haline getirir — ses işleme, fizik simülasyonu, finansal hesaplamalar.
- Wasm şunlar için kazanır: görüntü ve video işleme, ses sentezi ve analizi, veri sıkıştırma ve açma, kriptografik işlemler, oyun motorları, fizik simülasyonları, veritabanı sorgu yürütme.
- JavaScript şunlar için kazanır: DOM manipülasyonu, olay yönetimi, ağ isteği orkestrasyonu, framework'lerle UI oluşturma, string ve metin işleme, küçük veya seyrek çağrılan yardımcılar.
- Sınır kayıyor: Wasm, WASI ve bileşen modeli aracılığıyla web API'lerine erişim kazandıkça daha fazla iş yükü Wasm'e geçiyor, ancak JavaScript birincil arayüz katmanı olmaya devam ediyor.
Bileşen Modeli ve Wasm'in geleceği
WebAssembly Bileşen Modeli, Wasm'in ilk sürümünden bu yana en önemli gelişimidir. İlk Wasm'in temel sınırlamasını ele alır: modüllerin birbirleriyle etkileşim kurmak için standartlaştırılmış bir yol olmadan izole silolar halinde olması. Bileşen Modeli, Wasm modüllerinin yapı taşları gibi bir araya getirilmesine olanak tanıyan yüksek seviyeli, dilden bağımsız bir arayüz sistemi sunar.
Mevcut Wasm modelinde, bir modül yalnızca tamsayı ve kayan noktalı sayı alıp döndüren fonksiyonlar dışa aktarır. Bir modülün başka bir modüle bir string, dizi veya karmaşık veri yapısı geçirmesi gerekiyorsa, iki modül bir bellek düzeni kuralı üzerinde anlaşmalıdır — bir doğrusal bellek bölgesini paylaşmalı ve ayırma ile serbest bırakmayı koordine etmelidir. Bu kırılgandır ve dile özgüdür. Bileşen Modeli, bunu modül sınırları arasında string, kayıt, varyant, liste ve iç içe veri yapılarını yöneten standartlaştırılmış bir Arayüz Türleri sistemi tanımlayarak çözer.
Arayüz Türleri, bileşenler arasında akan verileri dilden bağımsız bir şekilde tanımlar. Bir bileşen, bir string alan ve iki tamsayı alanlı bir kayıt döndüren bir fonksiyon dışa aktarabilir ve Rust, C veya Go ile yazılmış olsun fark etmeksizin herhangi bir başka bileşen, diğer modülün iç bellek düzeni hakkında hiçbir şey bilmeden bu fonksiyonu çağırabilir. Çalışma zamanı, bağdaştırıcı mantığını otomatik olarak yönetir, çağıran bileşenin temsili ile çağrılanın temsili arasında çeviri yapar.
Gerçek dünya vaka çalışmaları
WebAssembly teorik bir teknoloji değildir. Bugün üretimdeki en zorlu web uygulamalarından bazılarını güçlendiriyor ve araçlar olgunlaştıkça ve performans avantajları inkâr edilemez hale geldikçe benimsenmesi hızlanıyor.
Figma: Wasm öncüsü
Figma, en bilinen Wasm başarı hikayesidir. Temel işleme motoru C++ ile yazılmıştır ve Emscripten aracılığıyla Wasm'a derlenmiştir. Figma, tüm C++ kod tabanını — Skia grafik kütüphanesi, HarfBuzz metin şekillendirici ve özel düzen motoru dahil — bir Wasm modülüne derler. JavaScript katmanı, giriş olaylarını ve DOM yönetimini üstlenirken Wasm, tüm işleme, isabet testi ve düzen hesaplamalarını yönetir. Sonuç, yerel masaüstü uygulamalarıyla rekabet eden performansta bir tarayıcı sekmesinde çalışan bir tasarım aracıdır.
SQLite: tarayıcıda veritabanı
SQLite, muhtemelen dünyada en yaygın dağıtılan Wasm modülüdür. SQLite projesi, tam SQLite veritabanı motorunu tarayıcıda çalıştıran resmi bir Wasm derlemesi sunar. Kullanıcılar, hiçbir sunucu bileşeni olmadan tamamen istemci tarafında bir SQLite veritabanını sorgulayabilir. Wasm derlemesi, Emscripten araç zinciri kullanılarak üretilir ve veritabanlarını IndexedDB'ye kalıcı hale getirmek için sanal dosya sistemi desteği içerir.
Etkileri oldukça önemlidir. İstemci tarafı sorgulama yeteneklerine ihtiyaç duyan uygulamalar — veri analizi araçları, raporlama panoları, bilimsel bilişim not defterleri — karmaşık toplamalar, birleştirmeler ve pencere fonksiyonlarını doğrudan tarayıcıda çalıştırmak için SQLite'i Wasm'da kullanabilir. sql.js ve better-sqlite3-wasm gibi kütüphaneler, SQLite Wasm modülünü temiz JavaScript API'leriyle sararak diğer herhangi bir npm paketi kadar kolay kullanılmasını sağlar.
Google Earth: 3D görüntüleme için Wasm
Tarayıcılar için Google Earth, 3D arazi işleme ve veri açma işlem hatları için Wasm kullanılarak yeniden oluşturuldu. Kullanıcı gezinirken, Wasm modülü sıkıştırılmış ikili veri alır, Wasm'a derlenmiş optimize C++ algoritmalarını kullanarak açar, geometriyi işlenebilir ağlara dönüştürür ve sonuçları hiçbir veri kopyalama ek yükü olmadan tek bir animasyon karesi bütçesi içinde WebGL'ye besler.
- Figma, tarayıcıda vektör grafik düzenleme için yerel sınıfı performans elde eden C++ işleme motoru için Wasm kullanır.
- SQLite, tam veritabanı motorunu istemci tarafında çalıştıran resmi bir Wasm derlemesi sunar; sunucu olmadan çevrimdışı sorgulama yetenekleri sağlar.
- Google Earth, akan coğrafi verilerin 60 FPS'de gerçek zamanlı açılması ve geometri işlenmesi için Wasm'e güvenir.
- Adobe, web için Photoshop'ta görüntü işleme filtreleri ve renk uzayı dönüşümleri için Wasm kullanır (Emscripten ile derlenmiş C++ kodu).
- Zoom, web istemcisinde video kod çözme ve arka plan bulanıklaştırma işleme için Wasm kullanır.
Uçta ve sunucusuzda Wasm
Sunucusuz platformlar, konteynırlara göre soğuk başlangıç avantajı nedeniyle WebAssembly'i uç bilişim için bir çalışma zamanı olarak benimsemiştir. Bir Wasm modülü, milisaniyeler içinde değil mikrosaniyeler içinde başlar — çünkü başlatılacak bir işletim sistemi, çatallanacak bir süreç veya başlatılacak bir çalışma zamanı yoktur. Soğuk başlangıç gecikmesinin kullanıcı deneyimini doğrudan etkilediği sunucusuz platformlar için bu dönüştürücüdür.
Cloudflare Workers, Wasm'i benimseyen ilk büyük platformdu. Workers, hem JavaScript hem de Wasm modüllerini çalıştırabilen V8 izolatları çalıştırır. Hesaplama mantığı için bir Wasm modülü kullanan bir Worker, soğuk başlangıçtan itibaren 5 milisaniyenin altında isteklere yanıt vermeye başlayabilir. Worker ortamı, Service Worker spesifikasyonuna dayalı sınırlı bir API kümesi — fetch, Cache, KV depolama ve Durable Objects — sağlar ve WASI desteğiyle derlenmiş Wasm modülleri bu API'leri ana bilgisayar ortamının içe aktarma mekanizması aracılığıyla kullanabilir.
Fastly'nin Compute@Edge'i, temel çalışma zamanı olarak Wasmtime'ı kullanır ve tüm hesaplamaların Wasm'a derlenmesini gerektirir. Geliştiriciler uç mantıklarını Rust, Go veya JavaScript ile yazar (Fastly bunu önceden Wasm'a derler) ve ortaya çıkan Wasm modülü Fastly'nin uç düğümlerinde çalışır. Bu model, güçlü güvenlik izolasyonu — her istek, paylaşılan durumu olmayan yeni bir Wasm örneğinde çalışır — ile uç bilişimi pratik kılan başlangıç hızını bir araya getirir.
Uç Wasm ekosistemi henüz genç ancak hızla büyüyor. Fermyon Spin ve Deislabs gibi platformlar, özellikle sunucusuz Wasm uygulamaları oluşturmak için tasarlanmış framework'ler sağlar. Bu framework'ler, WASI çalışma zamanı ayrıntılarını soyutlar ve her şeyi Wasm aracılığıyla çalıştırırken tanıdık desenler — HTTP işleyicileri, anahtar-değer depolama, zamanlanmış görevler — sunar. Vaat şudur: iş mantığınızı Wasm'a derlenen herhangi bir dilde bir kez yazın ve değişiklik yapmadan herhangi bir WASI uyumlu platforma dağıtın.
Wasm'a bugün başlamak
WebAssembly ile başlamanın en iyi yolu hedefinize bağlıdır. Wasm'i tarayıcıda kullanmak istiyorsanız, en hızlı yol Rust ve wasm-pack'tir. Rust'ı kurun, wasm32-unknown-unknown hedefini ekleyin ve wasm-pack new ile yeni bir proje oluşturun. Oluşturulan proje, JavaScript'ten çağrılabilen bir Wasm fonksiyonu içeren çalışan bir örnek, npm uyumlu bir paket üreten bir derleme betiği ve Wasm modülünüzü başsız bir tarayıcıda çalıştıran bir test düzeneği içerir.
Sunucu tarafı Wasm'i keşfetmek istiyorsanız, Wasmtime ve CLI aracıyla başlayın. wasmtime'ı kurun, WASI desteğiyle herhangi bir C veya Rust programını derleyin ve wasmtime program.wasm ile çalıştırın. Bir komut satırı programının Wasm'a derlenmiş halinin tıpkı yerel bir ikili dosya gibi çalıştığını göreceksiniz — stdin'den okur, stdout'a yazar, dosyalara erişir ve bir durum koduyla çıkar. Bir terminalde Wasm ile derlenmiş bir programı çalıştırma deneyimi şaşırtıcı derecede sorunsuzdur.
Uç ve sunucusuz denemeleri için Cloudflare Workers, Wasm'i destekleyen ücretsiz bir katman sağlar. Bir Rust fonksiyonu yazın, Wasm'a derleyin ve Cloudflare'in küresel ağına dağıtın. Çoğu konumdan 10 milisaniyenin altında yanıt süreleri görecek ve Wasm'in soğuk başlangıç endişesini nasıl ortadan kaldırdığını ilk elden deneyimleyeceksiniz.
Wasm ile en pratik ilk adım, tüm uygulamanızı yeniden yazmak değildir. Hesaplama açısından pahalı bir fonksiyon bulun — bir filtre, bir dönüşüm, bir doğrulama — onu Rust ile yeniden yazın, Wasm'a derleyin ve mevcut kod tabanınıza entegre edin. Performans farkını ölçün. Elli satırlık Wasm için 3 kat hızlanma gördüğünüzde, teknolojinin neden önemli olduğunu anlayacaksınız.
Araç ekosistemi hızla iyileşiyor. wasm-pack, cargo-generate ve wasm-tools olgun bir geliştirme iş akışı sağlar. Binaryen araç zinciri, Wasm modüllerini optimize etmek ve ikili boyutları yüzde 20 ila 30 oranında azaltmak için wasm-opt sunar. wasmtime ve wasmer çalışma zamanları, yerel yürütme ile performans açığını kapatmaya devam ediyor. Ve Bileşen Modeli, yakında Wasm modüllerini Wasm ilk çıktığında imkansız olan şekillerde birlikte çalışabilir hale getirecek.
WebAssembly, bildiğimiz web'in yerini almak için tasarlanmış bir teknoloji değildir. Platformun bir zenginleştirmesidir — JavaScript'in yapamadığını yapan ikinci bir çalışma zamanı. Bir dahaki sefere JavaScript'in dinamik doğasına karşı savaşıyormuş gibi hissettiren bir performans sorunuyla karşılaştığınızda, kodunuzun hesaplama ağırlıklı kısmının bir Wasm modülüne çıkarılıp çıkarılamayacağını düşünün. Araçlar üretime hazır, performans gerçek ve Wasm'in geleceği — Bileşen Modeli, WASI preview 2 ve daha geniş dil desteği ile — yalnızca daha da iyiye gidiyor.
Web platformu genişletilebilir olarak tasarlandı. WebAssembly, bu platforma on yıl içinde yapılmış en önemli eklentidir. Web'in sınırlarını zorlayan uygulamalar oluşturmak isteyen geliştiriciler için bunu anlamak bir seçenek değil, bir gerekliliktir.
