Sürekli olarak hızlı
Önceki makalelerimde, WebAssembly'nin C/C++ kitaplık ekosistemini web'e taşımanızı nasıl sağladığından bahsetmiştim. C/C++ kitaplıklarını kapsamlı şekilde kullanan bir uygulama olan squoosh, görüntüleri C++'tan WebAssembly'ye derlenmiş çeşitli codec'ler ile sıkıştırmanıza olanak tanır.
WebAssembly, .wasm
dosyalarında depolanan bayt kodunu çalıştıran düşük düzey bir sanal makinedir. Bu bayt kodu, ana makine sistemi için JavaScript'ten çok daha hızlı bir şekilde derlenip optimize edilebilecek şekilde güçlü bir şekilde yazılmış ve yapılandırılmıştır. WebAssembly, en başından itibaren korumalı alan ve yerleştirme düşünülerek yazılmış kodları çalıştırmak için bir ortam sağlar.
Deneyimlerime göre, web'deki performans sorunlarının çoğu zorunlu düzen ve aşırı boyamadan kaynaklanıyor ancak uygulamaların zaman zaman çok zaman alan, hesaplama açısından pahalı bir görev yapması gerekiyor. WebAssembly burada yardımcı olabilir.
The Hot Path
Squoosh'ta, bir resim arabelleğini 90 derecenin katları kadar döndüren bir JavaScript işlevi yazdık. OffscreenCanvas bu amaç için ideal olsa da hedeflediğimiz tarayıcılarda desteklenmemektedir ve Chrome'da biraz hatalı.
Bu işlev, bir giriş görüntüsünün her pikseli üzerinde yineleme yapar ve dönüşü sağlamak için bunu çıkış resminde farklı bir konuma kopyalar. 4.094 x 4.096 piksel (16 megapiksel) bir görüntü için iç kod bloğunun 16 milyonun üzerinde iterasyonu gerekir. Buna "kısa yol" denir. Çok sayıda yinelemeye rağmen test ettiğimiz üç tarayıcıdan ikisi, işlemi 2 saniye veya daha kısa sürede tamamlıyor. Bu tür etkileşim için kabul edilebilir bir süre.
for (let d2 = d2Start; d2 >= 0 && d2 < d2Limit; d2 += d2Advance) {
for (let d1 = d1Start; d1 >= 0 && d1 < d1Limit; d1 += d1Advance) {
const in_idx = ((d1 * d1Multiplier) + (d2 * d2Multiplier));
outBuffer[i] = inBuffer[in_idx];
i += 1;
}
}
Ancak bir tarayıcı 8 saniyeden uzun sürüyor. Tarayıcıların JavaScript'i optimize etme şekli çok karmaşıktır ve farklı motorlar farklı şeyler için optimizasyon yapar. Bazıları ham yürütme için, bazıları DOM ile etkileşim için optimize edilir. Bu durumda, bir tarayıcıda optimize edilmemiş bir yola ulaştık.
Öte yandan WebAssembly tamamen ham yürütme hızı üzerine kuruludur. Dolayısıyla, böyle bir kodun tüm tarayıcılarda hızlı, tahmin edilebilir performans elde etmek istiyorsak WebAssembly size yardımcı olabilir.
Öngörülebilir performans için WebAssembly
Genel olarak JavaScript ve WebAssembly aynı en yüksek performansı sağlayabilir. Ancak JavaScript için bu performansa yalnızca "hızlı yoldan" ulaşılabilir ve bu "hızlı yolda" kalmak genellikle zordur. WebAssembly'in sunduğu önemli avantajlardan biri, tarayıcılar arasında bile öngörülebilen performanstır. Katı yazma ve alt düzey mimari, derleyicinin, WebAssembly kodunun yalnızca bir kez optimize edilmesi gerekmesi ve her zaman "hızlı yolu" kullanması için daha güçlü garantiler vermesini sağlar.
WebAssembly için yazma
Daha önce, C/C++ kitaplıklarını alıp işlevlerini web'de kullanmak için WebAssembly'e derliyorduk. Kitaplıkların koduna dokunmadık, tarayıcı ile kitaplık arasında bir köprü oluşturmak için yalnızca küçük miktarda C/C++ kodu yazdık. Bu seferki motivasyonumuz farklı: WebAssembly'in avantajlarından yararlanabilmek için sıfırdan WebAssembly odaklı bir şey yazmak istiyoruz.
WebAssembly mimarisi
WebAssembly için kod yazarken WebAssembly'in aslında ne olduğu hakkında biraz daha bilgi sahibi olmanız faydalı olacaktır.
WebAssembly.org'dan alıntı yapmak için:
Bir C veya Rust kodu parçasını WebAssembly olarak derlediğinizde modül beyanı içeren bir .wasm
dosya elde edersiniz. Bu beyan, modülün ortamından beklediği "içe aktarma"ların listesinden, bu modülün ana makineye sunduğu dışa aktarma işlemlerinin (işlevler, sabitler, bellek parçaları) listesinden ve elbette içindeki işlevlere ait gerçek ikili talimatlardan oluşur.
Bu konuyu inceleyene kadar fark etmediğim bir şey: WebAssembly'i "stack tabanlı sanal makine" yapan yığın, WebAssembly modüllerinin kullandığı bellek parçasında depolanmaz. Paket tamamen sanal makine içindedir ve web geliştiricileri tarafından erişilemez (Geliştirici Araçları hariç). Bu nedenle, hiç ek belleğe ihtiyaç duymayan ve yalnızca sanal makine içi yığını kullanan WebAssembly modülleri yazılabilir.
Bizim durumumuzda, resmimizin piksellerine keyfi erişim izni vermek ve bu resmin döndürülmüş bir sürümünü oluşturmak için biraz ek bellek kullanmamız gerekir. WebAssembly.Memory
bunun içindir.
Bellek yönetimi
Genellikle, ek bellek kullandıktan sonra bu belleği bir şekilde yönetmeniz gerekir. Belleğin hangi bölümleri kullanılıyor? Hangileri ücretsiz?
Örneğin, C'de n
art arda baytlık bir bellek alanı bulan malloc(n)
işlevi vardır. Bu tür işlevlere "dağıtıcılar" da denir.
Elbette, kullanılan ayırıcının uygulanması WebAssembly modülünüze dahil edilmelidir ve dosya boyutunuzu artırır. Bu bellek yönetimi işlevlerinin boyutu ve performansı, kullanılan algoritmaya bağlı olarak oldukça önemli ölçüde değişiklik gösterebilir. Bu nedenle birçok dil, aralarından seçim yapabileceğiniz birden fazla uygulama sunar ("dmalloc", "emmalloc", "wee_alloc" vb.).
Bizim durumumuzda, WebAssembly modülünü çalıştırmadan önce giriş resminin boyutlarını (ve dolayısıyla çıkış resminin boyutlarını) biliyoruz. Burada bir fırsat gördük: Geleneksel olarak, giriş resminin RGBA arabelleğini bir WebAssembly işlevine parametre olarak iletir ve döndürülmüş resmi bir dönüş değeri olarak döndürürdük. Bu döndürülen değeri oluşturmak için ayırıcıyı kullanmamız gerekir. Ancak gereken toplam bellek miktarını bildiğimizden (giriş görüntüsünün boyutunun iki kat, giriş ve bir kez çıkış için bir kez), JavaScript kullanarak giriş resmini WebAssembly belleğine yerleştirebilir, 2. döndürülmüş bir resim oluşturmak için WebAssembly modülünü çalıştırabilir ve sonucu okumak için JavaScript'i kullanabiliriz. Bellek yönetimi kullanmadan da bu işlemi yapabiliriz.
Seçenek çok
WebAssembly-fy için kullanmak istediğimiz orijinal JavaScript işlevine bakarsanız bunun JavaScript'e özgü API'ler içermeyen, tamamen hesaplamaya dayalı bir kod olduğunu görebilirsiniz. Bu nedenle, bu kodu herhangi bir dile taşımak oldukça kolaydır. WebAssembly'e derlenen 3 farklı dili değerlendirdik: C/C++, Rust ve AssemblyScript. Her bir dil için yanıtlamamız gereken tek soru şudur: Bellek yönetimi işlevlerini kullanmadan ham belleğe nasıl erişiriz?
C ve Emscripten
Emscripten, WebAssembly hedefi için bir C derleyicisidir. Emscripten'in amacı, GCC veya clang gibi tanınmış C derleyicilerinin yerini almaktır ve çoğunlukla işaret uyumludur. Mevcut C ve C++ kodunun WebAssembly'e derlenmesini mümkün olduğunca kolaylaştırmak isteyen Emscripten'in misyonunun temel bir parçasıdır.
Ham belleğe erişmek C'nin doğasında vardır ve işaretçiler de bu nedenle mevcuttur:
uint8_t* ptr = (uint8_t*)0x124;
ptr[0] = 0xFF;
Burada 0x124
sayısını, işaretsiz 8 bitlik tamsayılara (veya baytlara) işaretçiye dönüştürüyoruz. Bu işlem, ptr
değişkenini 0x124
bellek adresinden başlayan ve diğer tüm diziler gibi kullanabileceğimiz bir diziye dönüştürür. Böylece, okuma ve yazma için tek tek baytlara erişebiliriz. Bizim durumumuzda, döndürmeyi gerçekleştirmek için yeniden sıralamak istediğimiz bir resmin RGBA arabelleğine bakıyoruz. Bir pikseli taşımak için aslında aynı anda 4 art arda bayt taşımamız gerekir (her kanal için bir bayt: K, G, B ve A). Bu işlemi kolaylaştırmak için imzalanmamış, 32 bitlik tam sayı dizisi oluşturabiliriz. Genellikle giriş resmimiz 4. adreste başlar ve çıkış resmimiz giriş görüntüsü bittikten hemen sonra başlar:
int bpp = 4;
int imageSize = inputWidth * inputHeight * bpp;
uint32_t* inBuffer = (uint32_t*) 4;
uint32_t* outBuffer = (uint32_t*) (inBuffer + imageSize);
for (int d2 = d2Start; d2 >= 0 && d2 < d2Limit; d2 += d2Advance) {
for (int d1 = d1Start; d1 >= 0 && d1 < d1Limit; d1 += d1Advance) {
int in_idx = ((d1 * d1Multiplier) + (d2 * d2Multiplier));
outBuffer[i] = inBuffer[in_idx];
i += 1;
}
}
JavaScript işlevinin tamamını C'ye taşıdıktan sonra emcc
ile C dosyasını derleyebiliriz:
$ emcc -O3 -s ALLOW_MEMORY_GROWTH=1 -o c.js rotate.c
Her zaman olduğu gibi emscripten, c.js
adlı bir yapıştırma kodu dosyası ve c.wasm
adlı bir wasm modülü oluşturur. wasm modülünün yalnızca yaklaşık 260 bayta sıkıştırıldığını, yapıştırma kodunun ise sıkıştırıldıktan sonra yaklaşık 3,5 KB olduğunu unutmayın. Biraz uğraştıktan sonra yapışkan kodu bıraktık ve vanilya API'leriyle WebAssembly modüllerini örneklendirdik.
C standart kitaplığından herhangi bir şey kullanmadığınız sürece Emscripten'de bu durumla genellikle karşılaşılabilir.
Rust
Rust; zengin türde bir sisteme sahip, çalışma zamanı bulunmayan ve bellek güvenliği ile iş parçacığı güvenliğini garanti eden bir sahiplik modeline sahip yeni ve modern bir programlama dilidir. Rust, temel bir özellik olarak WebAssembly'i de destekler. Rust ekibi, WebAssembly ekosistemine birçok mükemmel araç katkısında bulunmuştur.
Bu araçlardan biri, rustwasm çalışma grubunun wasm-pack
aracıdır. wasm-pack
, kodunuzu alıp webpack gibi paketleyicilerle hazır olarak çalışan web dostu bir modüle dönüştürür. wasm-pack
son derece kullanışlı bir deneyimdir ancak şu anda yalnızca Rust için kullanılabilir. Grup, WebAssembly'i hedefleyen diğer diller için destek eklemeyi düşünüyor.
Rust'ta dilim, C'deki dizilere benzer. C'de olduğu gibi, başlangıç adreslerimizi kullanan dilim oluşturmamız gerekir. Bu, Rust'un zorunlu kıldığı bellek güvenliği modeline aykırıdır. Bu nedenle, istediğimiz şekilde kod yazmak için unsafe
anahtar kelimesini kullanmamız gerekir. Bu anahtar, söz konusu modele uymayan kod yazmamıza olanak tanır.
let imageSize = (inputWidth * inputHeight) as usize;
let inBuffer: &mut [u32];
let outBuffer: &mut [u32];
unsafe {
inBuffer = slice::from_raw_parts_mut::<u32>(4 as *mut u32, imageSize);
outBuffer = slice::from_raw_parts_mut::<u32>((imageSize * 4 + 4) as *mut u32, imageSize);
}
for d2 in 0..d2Limit {
for d1 in 0..d1Limit {
let in_idx = (d1Start + d1 * d1Advance) * d1Multiplier + (d2Start + d2 * d2Advance) * d2Multiplier;
outBuffer[i as usize] = inBuffer[in_idx as usize];
i += 1;
}
}
Rust dosyalarını şunu kullanarak derleme:
$ wasm-pack build
yaklaşık 100 baytlık bir yapıştırma kodu içeren 7,6 KB'lık bir wasm modülü oluşturur (her ikisi de gzip'den sonra).
AssemblyScript
AssemblyScript, TypeScript-WebAssembly derleyicisi olmayı amaçlayan, oldukça genç bir projedir. Ancak, herhangi bir TypeScript'i tüketmeyeceğini unutmayın. AssemblyScript, TypeScript ile aynı söz dizimini kullanır ancak standart kitaplığı kendi kitaplığıyla değiştirir. Standart kitaplığı, WebAssembly'nin özelliklerini modeller. Bu, WebAssembly ile ilgili herhangi bir TypeScript'i derleyemeyeceğiniz, ancak bu anlamına da gelir. Bunun için WebAssembly yazmak için yeni bir programlama dili öğrenmeniz gerekmez.
for (let d2 = d2Start; d2 >= 0 && d2 < d2Limit; d2 += d2Advance) {
for (let d1 = d1Start; d1 >= 0 && d1 < d1Limit; d1 += d1Advance) {
let in_idx = ((d1 * d1Multiplier) + (d2 * d2Multiplier));
store<u32>(offset + i * 4 + 4, load<u32>(in_idx * 4 + 4));
i += 1;
}
}
rotate()
işlevimizin sahip olduğu küçük tür yüzeyi göz önüne alındığında, bu kodu AssemblyScript'e taşımak oldukça kolaydı. load<T>(ptr:
usize)
ve store<T>(ptr: usize, value: T)
işlevleri, ham belleğe erişmek için AssemblyScript tarafından sağlanır. AssemblyScript dosyamızı derlemek için sadece AssemblyScript/assemblyscript
npm paketini yükleyip
$ asc rotate.ts -b assemblyscript.wasm --validate -O3
AssemblyScript bize yaklaşık 300 baytlık bir wasm modülü ve hiçbir yapıştırıcı kod sağlar. Modül yalnızca standart WebAssembly API'leriyle çalışır.
WebAssembly Adli İncelemesi
Rust'ın 7,6 KB boyutu, diğer 2 dille karşılaştırıldığında şaşırtıcı derecede büyük. WebAssembly ekosisteminde, WebAssembly dosyalarınızı (oluşturuldukları dilden bağımsız olarak) analiz etmenize, neler olduğunu anlamanıza ve durumunuzu iyileştirmenize yardımcı olabilecek birkaç araç vardır.
Twiggy
Twiggy, Rust'un WebAssembly ekibi tarafından geliştirilen ve WebAssembly modülünden bir dizi yararlı veri çıkaran bir araçtır. Rust'a özgü olmayan bu araç, modülün çağrı grafiği gibi öğeleri incelemenize, kullanılmayan veya gereksiz bölümleri belirlemenize ve modülünüzün toplam dosya boyutuna hangi bölümlerin katkıda bulunduğunu anlamanıza olanak tanır. İkincisi, Twiggy'nin top
komutuyla yapılabilir:
$ twiggy top rotate_bg.wasm
Bu durumda, dosya boyutumuzun büyük kısmının ayırıcıdan kaynaklandığını görebiliriz. Kodumuz dinamik atama kullanmadığı için bu durum şaşırtıcıydı. "İşlev adları" alt bölümü de bu duruma katkıda bulunan önemli faktörlerden biridir.
wasm-strip
wasm-strip
, WebAssembly Binary Toolkit (wabt) araç setindeki bir araçtır. WebAssembly modüllerini incelemenize ve değiştirmenize olanak tanıyan birkaç araç içerir.
wasm2wat
, ikili wasm modülünü insanların okuyabileceği bir biçime dönüştüren bir sökücüdür. Wabt, okunabilir biçimi tekrar ikili wasm modülüne dönüştürmenizi sağlayan wat2wasm
öğesini de içerir. WebAssembly dosyalarımızı incelemek için bu iki tamamlayıcı aracı kullansak da wasm-strip
ürününün en kullanışlı araç olduğunu gördük. wasm-strip
, WebAssembly modülündeki gereksiz bölümleri ve meta verileri kaldırır:
$ wasm-strip rotate_bg.wasm
Bu işlem, rust modülünün dosya boyutunu 7,5 KB'tan 6,6 KB'ya (gzip'ten sonra) düşürür.
wasm-opt
wasm-opt
, Binaryen'in bir aracıdır.
Bir WebAssembly modülü gerekir ve modülü hem boyut hem de performans açısından yalnızca bayt koduna göre optimize etmeye çalışır. Emscripten gibi bazı araçlar bu aracı
zaten çalıştırırken, bazıları çalıştırmaz. Bu araçları kullanarak biraz daha bayt tasarrufu yapmaya çalışmak genellikle iyi bir fikirdir.
wasm-opt -O3 -o rotate_bg_opt.wasm rotate_bg.wasm
wasm-opt
ile gzip'ten sonra toplam 6,2 KB olacak şekilde birkaç bayt daha azaltabiliriz.
#![no_std]
Bazı danışmanlık ve araştırmalardan sonra Rust'ın standart kitaplığını kullanmadan Rust kodumuzu #![no_std]
özelliğini kullanarak yeniden yazdık. Bu işlem, dinamik bellek ayırmalarını da tamamen devre dışı bırakarak ayırıcı kodu modülümüzden kaldırır. Bu Rust dosyasını aşağıdakilerle derleme
$ rustc --target=wasm32-unknown-unknown -C opt-level=3 -o rust.wasm rotate.rs
wasm-opt
, wasm-strip
ve gzip'ten sonra 1,6 KB boyutunda bir wasm modülü elde edildi. C ve AssemblyScript tarafından oluşturulan modüllerden hâlâ daha büyük olsa da hafif kabul edilecek kadar küçüktür.
Performans
Yalnızca dosya boyutuna dayalı sonuçlara varmadan önce, bu yolculuğa dosya boyutunu değil performansı optimize etmek için çıktık. Peki performansı nasıl ölçtük ve sonuçlar ne oldu?
Karşılaştırma yapma
WebAssembly düşük düzey bir bayt kodu biçimi olmasına rağmen, ana makineye özgü makine kodu oluşturmak için bir derleyici üzerinden gönderilmesi gerekir. JavaScript gibi derleyici de birden fazla aşamada çalışır. Basitçe söylemek gerekirse: İlk aşama derleme işlemini çok daha hızlı gerçekleştirir ancak daha yavaş kod üretme eğilimindedir. Modül çalışmaya başladıktan sonra, tarayıcı hangi bölümlerin sık kullanıldığını gözlemler ve bunları daha iyi optimize eden ancak daha yavaş bir derleyici aracılığıyla gönderir.
Kullanım alanımızın ilginç yanı, bir resmi döndürme kodunun bir kez, belki de iki kez kullanılacak olmasıdır. Bu nedenle, çoğu durumda optimize edici derleyicinin avantajlarından yararlanamayız. Karşılaştırma yaparken bunu göz önünde bulundurmanız önemlidir. WebAssembly modüllerimizi bir döngüde 10.000 kez çalıştırmak gerçekçi olmayan sonuçlar verir. Gerçekçi sayılar elde etmek için modülü bir kez çalıştırıp tek bir çalıştırmadan elde edilen sayılara göre karar vermeliyiz.
Performans karşılaştırması
Bu iki grafik, aynı verilere ait farklı görünümlerdir. İlk grafikte tarayıcılara göre, ikinci grafikte ise kullanılan dile göre karşılaştırma yaparız. Lütfen logaritmik bir zaman ölçeği seçtiğimi unutmayın. Aynı makinede çalıştırılamayan bir tarayıcı dışında tüm karşılaştırmalarda aynı 16 megapiksel test resminin ve aynı ana makinenin kullanılması da önemlidir.
Bu grafikleri çok fazla analiz etmemiş olsaydık baştaki performans sorunumuzu çözmüş olduk: Tüm WebAssembly modülleri 500 ms veya daha kısa bir sürede çalışıyor. Bu, başlangıçta belirlediklerimizi onaylar: WebAssembly, size tahmin edilebilir bir performans sunar. Hangi dili seçersek seçelim, tarayıcılar ve diller arasındaki farklılık minimumdur. Daha doğrusu: Tüm tarayıcılarda JavaScript'in standart sapması yaklaşık 400 ms, tüm tarayıcılarda tüm WebAssembly modüllerimizin standart sapması ise yaklaşık 80 ms'dir.
Yapılması gerekenler
Diğer bir metrik de WebAssembly modülümüzü oluşturup squoosh ile entegre etmek için harcamanız gereken çabanın miktarı. Çalışmaya sayısal bir değer atamak zor olduğundan grafik oluşturmayacağım ancak belirtmek istediğim birkaç nokta var:
AssemblyScript sorunsuzdu. Bu araç, WebAssembly yazmak için TypeScript'i kullanmanıza olanak tanıyarak iş arkadaşlarımın kod incelemesini çok kolaylaştırıyor. Ayrıca, iyi performansa sahip çok küçük, yapıştırıcı içermeyen WebAssembly modülleri oluşturuyor. TypeScript ekosistemindeki araçlar (ör. prettier ve tslint) büyük olasılıkla sorunsuz çalışır.
Rust, wasm-pack
ile birlikte kullanıldığında da son derece kullanışlıdır ancak daha büyük WebAssembly projelerinde daha fazla uzmandır. Bağlamalar gerekirdi ve bellek yönetimi gerekliydi. Rekabetçi bir dosya boyutuna ulaşmak için ideal yoldan biraz sapmamız gerekti.
C ve Emscripten, kutudan çıkar çıkmaz çok küçük ve yüksek performanslı bir WebAssembly modülü oluşturdu ancak yapıştırma koduna atlayıp bunu en temel ihtiyaçlara indirgeme cesareti olmadan toplam boyut (WebAssembly modülü + yapıştırma kodu) oldukça büyük oluyor.
Sonuç
JS sıcak yolunuz varsa ve bunu WebAssembly ile daha hızlı veya daha tutarlı hale getirmek istiyorsanız hangi dili kullanmalısınız? Performansla ilgili sorularda olduğu gibi, yanıt şudur: Duruma bağlı. Peki ne gönderdik?
Kullandığımız farklı dillerin modül boyutu / performans dengesi açısından karşılaştırıldığında en iyi seçenek C veya AssemblyScript gibi görünüyor. Rust'u kullanıma sunmaya karar verdik. Bu kararın birden fazla nedeni vardır: Squoosh'ta şu ana kadar kullanıma sunulan tüm codec'ler Emscripten kullanılarak derlenmiştir. WebAssembly ekosistemi hakkındaki bilgilerimizi genişletmek ve üretimde farklı bir dil kullanmak istedik. AssemblyScript güçlü bir alternatiftir ancak proje nispeten genç ve derleyici, Rust derleyicisi kadar gelişmiş değildir.
Rust ile diğer diller arasındaki dosya boyutu farkı, dağılım grafiğinde oldukça belirgin görünse de gerçekte bu kadar büyük bir fark yoktur: 2 GB'ta bile 500 B veya 1,6 KB yüklemek saniyenin 1/10'undan kısa sürer. Rust'ın yakında modül boyutu açısından bu farkı kapatacağını umuyoruz.
Çalışma zamanı performansı açısından Rust, tarayıcılar genelinde AssemblyScript'e kıyasla daha hızlı bir ortalamaya sahiptir. Özellikle daha büyük projelerde Rust, manuel kod optimizasyonlarına gerek kalmadan daha hızlı kod üretme olasılığı daha yüksektir. Ancak bu, en rahat kullandığınız yöntemi kullanmanıza engel olmamalıdır.
Tüm söylenmesi gereken: AssemblyScript mükemmel bir keşif oldu. Web geliştiricilerinin yeni bir dil öğrenmek zorunda kalmadan WebAssembly modülleri oluşturmasına olanak tanır. AssemblyScript ekibi çok hızlı yanıt veriyor ve araç zincirlerini iyileştirmek için aktif olarak çalışıyor. İleride kesinlikle AssemblyScript'i dikkate alacağız.
Güncelleme: Pas
Bu makale yayınlandıktan sonra Rust ekibinden Nick Fitzgerald, dosya boyutunu optimize etmeyle ilgili bir bölüm içeren mükemmel Rust Wasm kitaplarını bize önerdi. Buradaki talimatları uygulamak (özellikle bağlantı süresi optimizasyonlarını ve manuel panik işlemeyi etkinleştirmek), "normal" Rust kodu yazmamızı ve dosya boyutunu büyütmeden Cargo
(Rust'un npm
) özelliğini kullanmaya devam etmemizi sağladı. Rust modülü, gzip'ten
sonra 370 B değerini alır. Ayrıntılar için lütfen Squoosh'ta açtığım PR'ye göz atın.
Bu yolculukta bize yardımcı oldukları için Ashley Williams, Steve Klabnik, Nick Fitzgerald ve Max Graey'e özel teşekkürlerimizi sunuyoruz.