- WebAssembly, 2017’de ilk kez yayımlanmasından bu yana C/C++ gibi düşük seviyeli dillerin çalıştırılmasını destekleyerek gelişti, ancak web platformunda hâlâ ikinci sınıf bir dil olarak ele alınıyor
- Yalnızca JavaScript Web API’leriyle doğrudan etkileşime girebiliyor ve WebAssembly’nin bunu yapabilmesi için karmaşık JS bağlama kodu (glue code) yazılması gerekiyor
- Bu yapı, yükleme sürecinin karmaşıklığı, performans ek yükü ve dile özgü araç zinciri kopukluğu gibi sorunlara yol açarak geliştirici deneyimini kötüleştiriyor
- Mozilla, bunu çözmek için WebAssembly Component Model önerisini sundu; bu sayede JS olmadan da standartlaştırılmış bir şekilde Web API çağrıları ve modül yükleme mümkün hale geliyor
- Bu model yerleşirse WebAssembly, tarayıcı içinde birinci sınıf bir çalışma ortamı haline gelerek sıradan geliştiricilerin de kolayca kullanabileceği bir temel sunabilir
WebAssembly’nin neden ikinci sınıf bir dil olarak görüldüğü
- WebAssembly, web platformuna erişimi yalnızca JavaScript üzerinden sağlayabiliyor; doğrudan Web API çağırma yetkisi yok
- JavaScript,
<script> etiketiyle kolayca yüklenebilirken WebAssembly için JS API üzerinden manuel bir yükleme süreci gerekiyor
WebAssembly.instantiateStreaming() gibi karmaşık API çağrıları yapılmalı; geliştiricinin bunları ezberlemesi ya da araçlarla otomatikleştirmesi gerekiyor
- esm-integration önerisi,
.wasm dosyalarının JS modül sistemi üzerinden doğrudan import edilmesini sağlayarak yükleme sürecini basitleştiriyor
<script type="module" src="/module.wasm"></script> biçiminde doğrudan yükleme mümkün
Web API erişimindeki kısıtlar
- JavaScript’te
console.log("hello, world") ile tek satırda yapılabilen bir işlem, WebAssembly’de JS belleğine erişim, string çözümleme ve fonksiyon sarmalama gibi karmaşık adımlar gerektiriyor
- WebAssembly,
console nesnesine veya DOM’a erişemediği için, JS tarafında bellek paylaşımı ve fonksiyon import/export üzerinden dolaylı çağrı yapılması gerekiyor
- Bu süreçte oluşan bağlama kodu (glue code) dile göre değişiyor ve
embind, wasm-bindgen gibi araçlarla otomatik üretiliyor
- Ancak bu da derleme karmaşıklığının artması, çalışma zamanı ek yükü ve diller arası uyumsuzluk gibi sorunlar doğuruyor
WebAssembly’nin birinci sınıf bir dil olamamasının teknik nedenleri
- Derleyici entegrasyonunun zorluğu: Her dilin derleyicisi, JS ve web platformu entegrasyon kodunu ayrı ayrı üretmek zorunda kalıyor; bu da yeniden kullanılamıyor
- Standart derleyicilerin uyumsuzluğu:
rustc --target=wasm ile üretilen dosya tarayıcıda doğrudan çalışmıyor
- Platform entegrasyonunu sağlayan resmî olmayan araç zincirlerinin ayrıca kurulması gerekiyor
- Belgelendirme ekosistemindeki eğilim: MDN gibi web belgeleri çoğunlukla JavaScript merkezli yazıldığından, diğer dil kullanıcıları için giriş eşiği yükseliyor
- Performans sorunu: JS bağlaması üzerinden geçen DOM çağrılarında, doğrudan çağrıya kıyasla %45 performans kaybı yaşanıyor
- Dodrio framework denemesinde JS glue kaldırıldığında DOM değişikliklerini uygulama süresi yarıya indi
- JavaScript bağımlılığı: WebAssembly’yi gerçek dünyada kullanabilmek için sonunda yine JS bilmek gerekiyor; bu da sızdıran soyutlama (leaky abstraction) sorununa yol açıyor
WebAssembly Component Model’in ortaya çıkışı
- WebAssembly Component Model, birden fazla dil ve çalışma zamanında ortak kullanılabilecek standartlaştırılmış bir yürütme birimi tanımlıyor
- Web API erişimi, modül yükleme ve bağlama süreçleri JS olmadan doğrudan gerçekleştirilebiliyor
- Farklı dillerde üretilebiliyor ve tarayıcı ya da Wasmtime gibi çeşitli çalışma zamanlarında destekleniyor
- Gerekli API’ler WIT (Interface Description Language) ile tanımlanıyor ve bunlar bileşen içinde doğrudan çağrılabiliyor
- Tarayıcı, bileşeni
<script type="module" src="component.wasm"></script> ile doğrudan yükleyebiliyor ve JS olmadan Web API bağlamasını otomatik olarak işleyebiliyor
JavaScript ile birlikte çalışabilirlik
- Component Model, hibrit uygulama yapısını da destekliyor
- Örneğin bir görüntü çözücüsü WebAssembly ile yazılıp JS tarafında
import { Image } from "image-lib.wasm"; biçiminde çağrılabiliyor
- JS, WebAssembly bileşenlerini normal modüller gibi import/export ederek kullanabiliyor
Gelecek görünümü ve katılım
- Mozilla, WebAssembly CG ile birlikte Component Model standardizasyonu üzerinde çalışıyor; Google da inceleme aşamasında
- Geliştiriciler, Jco veya Wasmtime üzerinden tarayıcıda ya da CLI’da deney yapabiliyor
- Bu model yerleşirse WebAssembly, “ileri düzey kullanıcı özelliği” olmaktan çıkıp sıradan geliştiricilerin de yararlanabileceği bir web teknolojisine dönüşebilir
4 yorum
Bu, sadece Mozilla tarzı bir temenniye daha yakın. Frontend, piyasa tepkisinin limbik sisteminden yapısal olarak çıkamaz. WebAssembly ortaya çıkar çıkmaz Doom 3 port edilmişti. DOM, modern tarayıcılarda zaten uzun zamandır hafif bir proxy nesnesine dönüşmüş durumda ve modern CPU’ların JavaScript’e özel instruction set’i ile tek çekirdeğin kuantumsal sınırları düşünüldüğünde, bu tür bir yaklaşımın piyasa değeri açısından üstünlük kazanacağı bir durum asla yaşanmayacaktır.
Electron içinde çalışan bir WebAssembly binary’sinin ne anlamı var? Bu bana sadece bir başka GitKraken CLI ya da Rust portlama şöhreti avı gibi görünüyor.
Diğer her şeyi bir kenara bıraksak bile, wasm modülünü
<script type="module" src="/module.wasm"></script>gibi dosya olarak ekleme yöntemi kulağa oldukça cazip geliyor.Ayrıca WebAssembly’ye giriş engelinin yüksek olduğu yönündeki iddiaların saçma olduğunu da mutlaka söylemek gerekir. Mesele sadece, bunun gerekli olma düzeyinin para ödeme isteğinden daha düşük olması. Hızlı ve düşük ayak izi istiyorsunuz ama DOM ve CSS de kullanmak mı istiyorsunuz? Bu ne biçim bir kara komedi?
Hacker News görüşleri
WebIDL’in WebAssembly’de desteklenmesine yönelik ilk hedeften vazgeçilip başka bir IDL yapılmak istenirken, DOM erişiminin olmayışının sorun olarak görülmemesi üzücü
Elbette piyasa gerçeklerini anlıyorum ama kaybedilen zamana hayıflanmadan edemiyorum
İlgili referans bağlantıları: commit kaydı, stringref ağıdı, ACM makalesi
Sonradan iki hedef daha eklendi: biri web dışı API desteği, diğeri de diller arası birlikte çalışabilirlikti
WebIDL, JS ile Web API’lerinin birleşimi olduğu için ifade gücü yüksekti ama bu hedeflerle çakışan birçok kavram içeriyordu
Bu yüzden component interface, ifade gücünü azaltıp çok daha taşınabilir bir kesişim kümesi yaklaşımını seçti
Ben şahsen DOM erişimini önemli buluyorum ama Wasm CG daha yüksek öncelikli işlerle meşguldü
Bu yazıyı yazma nedenim, bu sorunun hâlâ akılda olduğunu ve üzerinde çalışmaya devam etmeyi planladığımızı göstermekti
Toolchain ve build süreci o kadar karmaşık ki, her kullandığımda zihinsel yük hissediyorum
Performans glue olmadan çok daha iyi ama buna karşılık risk unsurları da daha fazla
Component model’in yeni bir karmaşıklık getirmemesini umuyorum ama çeşitli dil örneklerine bakınca tablo şimdiden epey kafa karıştırıcı görünüyor
Özellikle Go örneğinde üretilen dosya sayısı fazla ve geliştirici açısından tooling’in sadeleşmesine ciddi ihtiyaç var
Şu anda sanki karmaşıklık ortadan kaldırılmıyor da sadece başka yere taşınıyor gibi görünüyor
wasm component spesifikasyonu sürekli değiştiği için çok fazla churn yaşandı
Amaç, web geliştiricisinin doğrudan WIT yazmak zorunda kalmaması ve Web API’lerini bir kütüphane gibi kullanabilmesi
Ama daha gidilecek uzun bir yol var
Örneğin metin paylaşımı, medya paylaşımı, uygulama paylaşımı gibi parçalara ayrılsa hem güvenlik iyileşir hem de küçük ekipler tarayıcı alternatifleri üretebilir
Ama devasa web API’leri ve CSS’in büyüklüğü tarayıcı tekellerini ayakta tutan unsurlardan biri olduğu için, böyle girişimler zor görünüyor
Bir WebAssembly registry standardize edilip component’lerin kolayca birleştirilebilmesi güzel olurdu
Sonuçta web, dağıtık bir işletim sistemi tanımı inşa etme süreci
Kavramlardan kod örneklerine kadar iyi derlenmiş
JS ekosisteminde StarlingMonkey, ComponentizeJS, jco olmak üzere üç proje öne çıkıyor
Şu an en olgun toolchain Rust tarafında ama LLVM tabanlı dillerin (C/C++, Go, Python vb.) desteği de giderek iyileşiyor
WebAssembly’nin hedefi, yerel toolchain’e doğal biçimde karışan bir derleme hedefi olmak
Hâlâ dile özel glue kodunu ya da iki farklı runtime modelini anlamak gerekiyorsa, WebAssembly yine “yalnızca uç durumlarda kullanılan bir araç” olarak kalacak
Gerçek bir değişim yaratmak için genel build yolunu sadeleştirmek gerekiyor
Component Model’de bunun nasıl ele alındığı belirsiz
DOM tarayıcıdan tarayıcıya değişiyor ve özellikler sayfa her yüklendiğinde farklılaşabiliyor
JS bridge katmanında polyfill uygulamak kolay ama WIT arayüzlerinde runtime metod algılama ya da polyfill zor
Performansın ötesinde, ekosistemin esnekliği de önemli
JS glue kodunu elle yönetmek ya da otomatik üretim araçlarına bel bağlamak büyük bir geri adım gibi hissettiriyor
Dodrio deneyinde glue’yu atlayıp %45 ek yük azalması elde edilmesi etkileyici
Yalnız, WebAssembly Component Model’in Web API’leriyle doğrudan etkileşime girdiğinde bellek yönetiminin nasıl yapıldığını merak ediyorum
Wasm GC önerisinin DOM referanslarını elde tutmak için kullanılıp kullanılmadığını, yoksa hâlâ JS GC’ye mi bel bağlandığını öğrenmek isterim
Wasm’ın gerçekten birinci sınıf vatandaş hâline gelmesini umuyorum
Ama şu anda IPC hâlâ verimsiz ve bellek sayfası düzeyinde aktarım gibi bir yönteme ihtiyaç olduğunu düşünüyorum
Herhangi birinin bilgisayarımda karmaşık programlar çalıştırmasına izin vermek güvenlik açısından çılgınca bir fikirdi, ama pratikte bunu yaptık
JS yüzünden 20 yıl boyunca sayısız tarayıcı güvenlik açığı yaşadık ama artık tasarım ilkeleri ve hafifletme yöntemleri yerleşmiş durumda
Şimdi çıkıp bunu başka bir riskli çalıştırma paradigmasıyla değiştirmeye çalışmak hem ironik hem de bir bakıma güzel
Mobil işletim sistemleri bunu masaüstüne göre çok daha iyi yapıyor
Mühendis odaklı tasarlanıyorlar ve yazar(author) dostu bir varsayılan iş akışı sunmuyorlar
Yine de bu sorunları dert eden insanların hâlâ olması sevindirici
DOM API’lerini bire bir eşlemek için yalnızca 2 kat daha hızlı string işleme uğruna aşırı mühendislik yapılıyor gibi geliyor
WebGL2, WebGPU, WebAudio gibi API’lerde JS shim maliyeti zaten önemsiz düzeyde
Asıl problem GPU buffer kopyalama gibi yerlerde ama component model orada yardımcı olmuyor
WebGL2 ya da WebGPU’da on binlerce draw call’u test eden bir benchmark görmek isterim
Performansın yanı sıra geliştirici deneyimi (DX) iyileştirmesi de önemli
Şu anda başlamak çok zor ve avantajlardan yararlanmak için herkesin uzman olması gerekiyor
Native uygulama düzeyinde verimlilikle rekabet edebilirse, web’in geleceği için vizyoner bir değişim olur
Kodlama ajanları çağında sözünü ettikleri DX iyileştirmesi artık o kadar önemli değil