WebAssembly Nedir?
WebAssembly (kısaca Wasm), tarayıcıda ve tarayıcı dışında çalışabilen, düşük seviyeli, ikili bir komut seti formatıdır. C, C++, Rust gibi dillerle yazılmış kodu derleyip bu formata dönüştürebilir, ardından bir sanal makinede çalıştırabilirsiniz. Amaç, JavaScript'in yerini almak değil; hesaplama yoğun işleri JavaScript'in yanında, öngörülebilir bir performansla yürütmektir.
Wasm bir programlama dili değildir. Sizin yazdığınız kod değil, derleyicinin ürettiği hedef formattır. Bu ayrımı baştan netleştirmek gerekir; çünkü "Wasm ile uygulama yazacağım" cümlesi, aslında "kodu Wasm'a derleyeceğim" anlamına gelir.
Neden Var?
Tarayıcıda yüksek performans gerektiren işler (görüntü işleme, oyun motorları, video kodlama, kriptografi, veri sıkıştırma) JavaScript ile yapılabilir ama belirli bir noktadan sonra yönetimi ve performansı zorlaşır. Wasm şu özellikleriyle bu boşluğu doldurur:
- İkili format: Metin yerine bayt kodu olduğu için ayrıştırma hızlıdır ve dosya boyutu küçüktür.
- Öngörülebilir çalışma: Bellek erişimi doğrusal bir bellek alanıyla sınırlıdır; bu, hem güvenliği hem de optimizasyonu kolaylaştırır.
- Dil bağımsızlığı: Aynı
.wasmçıktısı tarayıcıda, Node.js'te veya gömülü bir runtime'da çalışabilir. - Sandbox modeli: Modül, kendisine açıkça verilmeyen bir kaynağa (dosya, ağ, DOM) erişemez.
Bu son madde kritik: Wasm modülü tek başına "hiçbir şey yapamaz". Ona yetenekleri host ortamı (tarayıcı ya da runtime) verir. Güvenlik modelinin temeli budur.
Hedef Ortamlar
Wasm iki ana bağlamda karşımıza çıkar:
- Tarayıcı: JavaScript,
WebAssemblyAPI'si üzerinden modülü yükler ve çağırır. DOM'a doğrudan erişim yoktur; JavaScript köprüsü gerekir. - Tarayıcı dışı: WASI (WebAssembly System Interface) ile dosya sistemi, saat, rastgele sayı gibi yetenekler tanımlanır. Sunucu tarafı, edge fonksiyonları, plugin sistemleri bu modeli kullanır.
WASI'nin sürümleri ve desteklenen yetenek kümeleri runtime'a göre değişir. Bir runtime'da çalışan modülün başka bir runtime'da çalışacağını varsaymayın; kullandığınız runtime'ın hangi WASI sürümünü desteklediğini belgelemesinden doğrulayın.
Önkoşullar
- JavaScript ve tarayıcı çalışma modeline aşinalık.
- En az bir sistem dili (Rust, C/C++) ile derleme araç zinciri kurabilme.
- Tarayıcı geliştirici araçlarında Network ve Console sekmelerini okuma alışkanlığı.
Sürüm numarası vermiyorum; çünkü Wasm ekosistemi (WASI, bileşen modeli, runtime'lar) hızlı değişiyor ve burada sabit bir sürüm yazmak kısa sürede yanıltıcı olur. Kullandığınız aracın resmi dokümantasyonundaki sürüm bilgisini esas alın.
Adım Adım: Tarayıcıda Basit Bir Wasm Modülü
Aşağıdaki örnek, elle yazılmış minimal bir WAT (WebAssembly Text) parçasını .wasm'a çevirip JavaScript'ten çağırma akışını gösterir. WAT, Wasm'ın okunabilir metin gösterimidir; üretimde bunu elle yazmazsınız ama formatı anlamak için faydalıdır.
1. Modülü tanımla
topla.wat dosyası:
(module
(func $topla (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add)
(export "topla" (func $topla))
)
Bu modül iki i32 alıp toplamını döndüren tek bir fonksiyon dışa aktarır. Bellek, tablo veya içe aktarım yok; bu yüzden en sade örnektir.
2. .wasm'a derle
WAT'ı ikili formata çevirmek için wat2wasm aracını (WABT paketi içinde gelir) kullanabilirsiniz:
wat2wasm topla.wat -o topla.wasm
Komut başarılı olursa aynı dizinde topla.wasm oluşur. Aracın kurulum adımları için WABT projesinin kendi dokümantasyonuna bakın.
3. Tarayıcıda yükle ve çağır
<!doctype html>
<html lang="tr">
<body>
<script>
async function calistir() {
const yanit = await fetch('topla.wasm');
const baytlar = await yanit.arrayBuffer();
const { instance } = await WebAssembly.instantiate(baytlar);
const sonuc = instance.exports.topla(3, 4);
console.log('Sonuç:', sonuc); // 7
}
calistir();
</script>
</body>
</html>
Beklenen davranış: Konsolda Sonuç: 7 görünür. WebAssembly.instantiate bir Promise döner; instance.exports üzerinden dışa aktarılan fonksiyona erişilir.
Dikkat: Bu dosyayı file:// üzerinden açarsanız fetch çoğu tarayıcıda engellenir. Basit bir yerel HTTP sunucusu üzerinden servis edin.
Yaygın Hatalar
- DOM'a doğrudan erişmeye çalışmak. Wasm modülü DOM görmez. DOM işlemleri JavaScript'te yapılır; modül ile JS arasında veri alışverişi köprü üzerinden olur.
- Sık sık sınır geçişi yapmak. Her JS↔Wasm çağrısı bir maliyet taşır. Küçük işlemleri tek tek çağırmak yerine, toplu iş yapan fonksiyonlar tasarlayın.
- Belleği yönetmeyi unutmak. Modülün doğrusal belleğine yazdığınız veriyi, işi bitince serbest bırakmazsanız bellek şişer. Dilinizin (Rust/C++) bellek yönetim kuralları Wasm'da da geçerlidir.
- Yanlış tipleri geçirmek. Wasm yalnızca
i32,i64,f32,f64gibi temel tipleri doğrudan tanır. String ve nesneler için serileştirme ve bellek üzerinden paylaşım gerekir. - Modülü her seferinde yeniden derlemek.
WebAssembly.compile/instantiatepahalıdır; aynı modülü tekrar tekrar derlemek yerine önbelleğe alın.
Güvenlik Tarafı
Wasm'ın güvenlik vaadi "sandbox"tır; ama bu, otomatik güvenlik anlamına gelmez.
- Yetenek modeli: Modül yalnızca host'un verdiği içe aktarımları kullanabilir. Gereksiz içe aktarım açmayın.
- Bellek sınırı: Modül kendi doğrusal belleği dışına yazamaz; bu, klasik bellek bozulmalarını sınırlar. Ancak modül içindeki mantık hataları (örneğin yanlış indeksleme) hâlâ uygulama düzeyinde sorunlara yol açabilir.
- Üçüncü taraf modüller: Dışarıdan aldığınız
.wasmdosyasını, tıpkı bir bağımlılık gibi değerlendirin. Kaynağını, derleme zincirini ve ne istediğini (hangi içe aktarımları) bilmiyorsanız çalıştırmayın. - Tarayıcı tarafı: Wasm, tarayıcının aynı-köken (same-origin) ve CSP kurallarını atlamaz. Yine de modüle verdiğiniz JS köprüsü, dolaylı bir saldırı yüzeyi olabilir; köprüyü minimum tutun.
Ne Zaman Kullanmalı, Ne Zaman Kullanmamalı?
Uygun olduğu durumlar:
- Hesaplama yoğun, sıcak döngüler (görüntü/ses işleme, fizik, kriptografi).
- Mevcut C/C++/Rust kod tabanını tarayıcıda yeniden kullanmak.
- Farklı dillerden gelen eklentileri izole biçimde çalıştırmak (plugin sistemleri).
Uygun olmadığı durumlar:
- Basit DOM manipülasyonu ve form işlemleri (JavaScript yeterli ve daha basit).
- Küçük, seyrek çalışan fonksiyonlar (köprü maliyeti kazancı yer bitirir).
- Ekosistem olgunluğu kritikse: araç zincirleri ve standartlar hâlâ gelişiyor.
"Geleceğin Teknolojisi mi?"
Wasm bugünün teknolojisidir; tarayıcılarda yaygın desteklenir ve üretimde kullanılır. "Gelecek" tartışması daha çok iki eksende sürüyor: tarayıcı dışı kullanımın (WASI, edge, plugin) olgunlaşması ve bileşen modelinin (component model) dil arası entegrasyonu standartlaştırması. Bu alanlar aktif geliştiriliyor; kesin bir "şu tarihte şu olacak" demek doğru olmaz.
Pratik sonuç şu: Wasm'ı gümüş kurşun olarak değil, belirli problemler için elinizdeki araçlardan biri olarak değerlendirin. Ölçün, köprü maliyetini hesaba katın, güvenlik modelini anlayın ve gereksiz yere JavaScript'in yerine geçirmeye çalışmayın.