Dukungan untuk 
teknologi WebAssembly (Wasm) telah muncul di browser relatif baru-baru ini. Tetapi teknologi ini juga dapat memperluas kemampuan web, menjadikannya sebuah platform yang mampu mendukung aplikasi seperti itu yang biasanya dianggap sebagai desktop.
Menguasai WebAssembly bisa menjadi tugas yang menakutkan bagi pengembang web. Namun, kompiler 
AssemblyScript dapat memperbaiki situasi.
Penulis artikel, yang kami terbitkan hari ini, menawarkan pertama untuk berbicara tentang mengapa WebAssembly adalah teknologi yang sangat menjanjikan, dan kemudian untuk melihat bagaimana AssemblyScript dapat membantu membuka potensi Wasm.
Perakitan web
WebAssembly dapat disebut bahasa tingkat rendah untuk browser. Ini memberi pengembang kemampuan untuk membuat kode yang mengkompilasi menjadi sesuatu selain JavaScript. Ini memungkinkan program yang dimasukkan dalam halaman web berfungsi hampir secepat aplikasi asli untuk berbagai platform. Program semacam itu dijalankan dalam lingkungan yang terbatas dan aman.
Perwakilan tim yang bertanggung jawab untuk pengembangan semua browser terkemuka (Chrome, Firefox, Safari dan Edge) terlibat dalam pembuatan standar WebAssembly. Mereka menyetujui 
arsitektur sistem pada awal 2017. Sekarang semua browser di atas mendukung WebAssembly. Bahkan, teknologi ini dapat digunakan di 
sekitar 87% browser.
Kode WebAssembly ada dalam format biner. Ini berarti bahwa kode tersebut lebih kecil dari kode JavaScript yang sama dan memuat lebih cepat. Kode Wasm, selain itu, dapat disajikan dalam 
format teks , sehingga orang dapat membaca dan mengeditnya.
Ketika standar WebAssembly pertama kali muncul, beberapa pengembang berpikir bahwa itu bisa menggantikan JavaScript dan menjadi bahasa utama web. Tapi WebAssembly paling baik dilihat sebagai alat baru yang terintegrasi dengan baik dengan platform web yang ada. Ini adalah salah satu 
tujuan prioritasnya .
Alih-alih mengganti JavaScript di mana bahasa ini telah digunakan untuk waktu yang lama dan berhasil, WebAssembly memberikan peluang menarik baru bagi pengembang web. Benar, kode Wasm tidak memiliki akses langsung ke DOM, sehingga sebagian besar proyek web yang ada akan terus menggunakan JavaScript. Bahasa ini, selama bertahun-tahun pengembangan dan optimalisasi, sudah cukup cepat. Dan WebAssembly memiliki 
aplikasi sendiri:
- Game
- Perhitungan ilmiah, visualisasi, simulasi.
- Aplikasi CAD.
- Mengedit gambar dan video.
Semua penggunaan ini untuk Wasm dipersatukan oleh apa yang masing-masing aplikasi mereka biasanya dianggap sebagai desktop. Tetapi karena kenyataan bahwa WebAssembly memungkinkan Anda untuk mencapai tingkat kinerja yang mendekati asli, banyak aplikasi serupa sekarang dapat diimplementasikan menggunakan platform web.
WebAssembly dapat memanfaatkan proyek web yang ada. Contohnya adalah proyek 
Figma . Berkat penggunaan Wasm, waktu pemuatan proyek ini meningkat secara signifikan. Jika situs web menggunakan kode yang melakukan perhitungan berat, maka, untuk meningkatkan kinerja situs web ini, masuk akal untuk mengganti hanya kode tersebut dengan analog WebAssembly.
Anda mungkin ingin mencoba menggunakan WebAssembly di proyek Anda sendiri. Bahasa ini dapat dipelajari dan ditulis 
langsung di situ . Namun, bagaimanapun, WebAssembly awalnya dikembangkan sebagai 
target kompilasi untuk bahasa lain. Itu 
dirancang dengan dukungan yang baik untuk C dan C ++. Dukungan 
eksperimental Wasm muncul di Go 1.11. Banyak upaya yang dilakukan untuk menulis aplikasi Wasm di 
Rust .
Tetapi sangat mungkin bahwa pengembang web tidak ingin mempelajari C, C ++, Go, atau Rust hanya untuk menggunakan WebAssembly. Apa yang mereka lakukan Jawaban untuk pertanyaan ini dapat memberikan AssemblyScript.
AssemblyScript
AssemblyScript adalah kompiler yang mengubah kode TypeScript ke kode WebAssembly. TypeScript adalah bahasa yang dikembangkan oleh Microsoft. Ini adalah superset dari JavaScript, menampilkan dukungan tipe yang ditingkatkan dan beberapa fitur lainnya. TypeScript telah menjadi bahasa yang cukup 
populer . Perlu dicatat bahwa AssemblyScript mampu mengkonversi ke Wasm hanya set konstruksi TypeScript yang terbatas. Ini berarti bahwa bahkan seseorang yang tidak terbiasa dengan TypeScript dapat dengan cepat mempelajari bahasa ini pada tingkat yang cukup untuk menulis kode yang dipahami oleh AssemblyScript.
Selain itu, mengingat fakta bahwa TypeScript sangat mirip dengan JavaScript, kita dapat mengatakan bahwa teknologi AssemblyScript memungkinkan pengembang web untuk dengan mudah mengintegrasikan modul Wasm ke dalam proyek mereka tanpa perlu mempelajari bahasa yang sama sekali baru.
Contoh
Mari kita menulis modul AssemblyScript pertama kami. Semua kode yang akan kita diskusikan sekarang dapat ditemukan di 
GitHub . Untuk 
mendukung WebAssembly, kita memerlukan setidaknya 
Node.js 8.
Buat direktori baru, inisialisasi proyek npm dan instal AssemblyScript:
mkdir assemblyscript-demo cd assemblyscript-demo npm init npm install --save-dev github:AssemblyScript/assemblyscript 
Perhatikan bahwa AssemblyScript harus diinstal langsung dari 
repositori GitHub proyek. AssemblyScript belum diterbitkan dalam npm, karena pengembang 
belum menganggapnya siap untuk digunakan secara luas.
Kami akan membuat file tambahan menggunakan perintah 
asinit termasuk dalam AssemblyScript:
 npx asinit . 
Sekarang bagian 
scripts package.json kami harus mengambil bentuk berikut:
 {  "scripts": {    "asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --sourceMap --validate --debug",    "asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --sourceMap --validate --optimize",    "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized"  } } 
File 
index.js terletak di folder root proyek akan terlihat seperti ini:
 const fs = require("fs"); const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/optimized.wasm")); const imports = {  env: {    abort(_msg, _file, line, column) {       console.error("abort called at index.ts:" + line + ":" + column);    }  } }; Object.defineProperty(module, "exports", {  get: () => new WebAssembly.Instance(compiled, imports).exports }); 
Ini memungkinkan Anda untuk memasukkan modul WebAssembly dalam kode Anda menggunakan perintah need. Yaitu - dengan cara yang sama seperti modul JavaScript biasa terhubung.
Folder 
assembly berisi file 
index.ts . Ini memiliki kode sumber yang ditulis sesuai dengan aturan AssemblyScript. Kode boilerplate yang dihasilkan secara otomatis adalah fungsi sederhana untuk menambahkan dua angka:
 export function add(a: i32, b: i32): i32 {  return a + b; } 
Mungkin Anda mengharapkan tanda tangan dari fungsi yang mirip terlihat seperti 
add(a: number, b: number): number . Jadi akan terlihat jika ditulis dalam TypeScript biasa. Namun di sini, alih-alih tipe 
number , tipe 
i32 . Ini terjadi karena kode AssemblyScript menggunakan 
tipe WebAssembly spesifik untuk bilangan bulat dan angka floating point, daripada tipe 
angka generik dari TypeScript.
Mari kita kumpulkan proyek:
 npm run asbuild 
File-file berikut ini akan muncul di folder 
build :
 optimized.wasm optimized.wasm.map optimized.wat untouched.wasm untouched.wasm.map untouched.wat 
Ada versi perakitan yang dioptimalkan dan teratur. Setiap versi majelis memberi kita file biner .wasm, 
peta peta .wasm.map, dan representasi tekstual dari kode biner dalam file .wat. Presentasi pengujian kode Wasm dimaksudkan untuk programmer, tetapi kami bahkan tidak akan melihat file ini. Sebenarnya, salah satu alasan untuk menggunakan AssemblyScript adalah karena menghilangkan kebutuhan untuk bekerja dengan kode Wasm.
Sekarang mari kita jalankan Node.js dalam mode REPL dan pastikan bahwa modul Wasm yang dikompilasi dapat digunakan dengan cara yang sama seperti modul JS biasa:
 $ node Welcome to Node.js v12.10.0. Type ".help" for more information. > const add = require('./index').add; undefined > add(3, 5) 8 
Secara umum, ini semua yang diperlukan untuk menggunakan teknologi WebAssembly di Node.js.
Melengkapi proyek dengan naskah pengamat
Untuk membangun kembali modul secara otomatis selama pengembangan ketika membuat perubahan, saya sarankan menggunakan paket 
onchange . Faktanya adalah bahwa AssemblyScript 
belum memiliki sistem sendiri untuk memonitor perubahan file. Instal paket onchange:
 npm install --save-dev onchange 
Tambahkan 
asbuild:watch script ke 
package.json . 
Bendera -i disertakan dalam perintah sehingga proses pembangunan dimulai satu kali ketika skrip dipanggil, sebelum semua peristiwa terjadi.
 {  "scripts": {    "asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --sourceMap --validate --debug",    "asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --sourceMap --validate --optimize",    "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized",    "asbuild:watch": "onchange -i 'assembly/**/*' -- npm run asbuild"  } } 
Sekarang, alih-alih terus menjalankan perintah 
asbuild , jalankan saja 
asbuild:watch sekali.
Performa
Kami akan menulis tes sederhana yang akan mengevaluasi tingkat kinerja kode Wasm. Ruang lingkup utama WebAssembly adalah untuk menyelesaikan tugas-tugas yang menggunakan prosesor secara intensif. Sebagai contoh, ini adalah semacam perhitungan "berat". Mari kita membuat fungsi yang mencari tahu apakah angka tertentu adalah prima.
Implementasi JS dasar dari fungsi serupa ditunjukkan di bawah ini. Ini diatur dengan sangat sederhana, memeriksa angka dengan kekerasan, tetapi untuk tujuan kami ini cocok, karena melakukan perhitungan dalam jumlah besar.
 function isPrime(x) {    if (x < 2) {        return false;    }    for (let i = 2; i < x; i++) {        if (x % i === 0) {            return false;        }    }    return true; } 
Fungsi serupa, ditulis untuk kompiler AssemblyScript, terlihat hampir sama. Perbedaan utama adalah adanya anotasi jenis dalam kode:
 function isPrime(x: u32): bool {    if (x < 2) {        return false;    }    for (let i: u32 = 2; i < x; i++) {        if (x % i === 0) {            return false;        }    }    return true; } 
Untuk menganalisis kinerja kode, kami akan menggunakan paket 
Benchmark.js . Pasang itu:
 npm install --save-dev benchmark 
Buat file 
benchmark.js :
 const Benchmark = require('benchmark'); const assemblyScriptIsPrime = require('./index').isPrime; function isPrime(x) {    for (let i = 2; i < x; i++) {        if (x % i === 0) {            return false;        }    }    return true; } const suite = new Benchmark.Suite; const startNumber = 2; const stopNumber = 10000; suite.add('AssemblyScript isPrime', function () {    for (let i = startNumber; i < stopNumber; i++) {        assemblyScriptIsPrime(i);    } }).add('JavaScript isPrime', function () {    for (let i = startNumber; i < stopNumber; i++) {        isPrime(i);    } }).on('cycle', function (event) {    console.log(String(event.target)); }).on('complete', function () {    const fastest = this.filter('fastest');    const slowest = this.filter('slowest');    const difference = (fastest.map('hz') - slowest.map('hz')) / slowest.map('hz') * 100;    console.log(`${fastest.map('name')} is ~${difference.toFixed(1)}% faster.`); }).run(); 
Inilah yang saya berhasil dapatkan setelah menjalankan perintah 
node benchmark di komputer saya:
 AssemblyScript isPrime x 74.00 ops/sec ±0.43% (76 runs sampled) JavaScript isPrime x 61.56 ops/sec ±0.30% (64 runs sampled) AssemblyScript isPrime is ~20.2% faster. 
Seperti yang Anda lihat, implementasi AssemblyScript dari algoritma itu 20% lebih cepat daripada implementasi JS. Namun, perhatikan bahwa tes ini adalah 
microbenchmark . Jangan terlalu mengandalkan hasilnya.
Untuk menemukan hasil yang lebih dapat diandalkan dari penelitian kinerja proyek-proyek AssemblyScript - Saya sarankan melihat 
ini dan tolok ukur 
ini .
Menggunakan Modul Wasm di Halaman Web
Mari kita gunakan modul Wasm kami di halaman web. Kami mulai dengan membuat file 
index.html dengan konten berikut:
 <!DOCTYPE html> <html>    <head>        <meta charset="utf-8" />        <title>AssemblyScript isPrime demo</title>    </head>    <body>        <form id="prime-checker">            <label for="number">Enter a number to check if it is prime:</label>            <input name="number" type="number" />            <button type="submit">Submit</button>        </form>        <p id="result"></p>        <script src="demo.js"></script>    </body> </html> 
Sekarang buat file 
demo.js yang kodenya ditunjukkan di bawah ini. Ada 
banyak cara untuk memuat modul WebAssembly. Yang paling efisien adalah mengkompilasi dan menginisialisasi mereka dalam mode streaming menggunakan fungsi 
WebAssembly.instantiateStreaming . Harap perhatikan bahwa kami perlu mendefinisikan kembali fungsi 
batal , yang dipanggil jika beberapa 
pernyataan tidak dieksekusi.
 (async () => {    const importObject = {        env: {            abort(_msg, _file, line, column) {                console.error("abort called at index.ts:" + line + ":" + column);            }        }    };    const module = await WebAssembly.instantiateStreaming(        fetch("build/optimized.wasm"),        importObject    );    const isPrime = module.instance.exports.isPrime;    const result = document.querySelector("#result");    document.querySelector("#prime-checker").addEventListener("submit", event => {        event.preventDefault();        result.innerText = "";        const number = event.target.elements.number.value;        result.innerText = `${number} is ${isPrime(number) ? '' : 'not '}prime.`;    }); })(); 
Selanjutnya, instal paket 
server statis . Kita memerlukan server karena fakta bahwa untuk menggunakan fungsi 
WebAssembly.instantiateStreaming , modul harus diservis menggunakan 
application/wasm MIME 
application/wasm .
 npm install --save-dev static-server 
Tambahkan skrip yang sesuai ke 
package.json :
 {  "scripts": {    "serve-demo": "static-server"  } } 
Sekarang 
npm run serve-demo dan buka URL host lokal di browser. Jika Anda memasukkan nomor tertentu dalam formulir, Anda dapat mengetahui apakah itu sederhana atau tidak. Sekarang, dalam mengembangkan AssemblyScript, kita telah jauh dari menulis kode untuk menggunakannya di Node.js dan di halaman web.
Ringkasan
WebAssembly, dan karenanya AssemblyScript, tidak dapat entah bagaimana mempercepat situs apa pun secara ajaib. Tapi Wasm tidak pernah ditugaskan untuk mempercepat segalanya. Teknologi ini luar biasa karena membuka jalan ke web untuk aplikasi jenis baru.
Hal serupa dapat dikatakan tentang AssemblyScript. Teknologi ini menyederhanakan akses ke WebAssembly untuk sejumlah besar pengembang. Hal ini memungkinkan, ketika membuat kode dalam bahasa yang dekat dengan JavaScript, untuk menggunakan kemampuan WebAssembly untuk memecahkan masalah komputasi yang kompleks.
Pembaca yang budiman! Bagaimana Anda menilai prospek untuk menggunakan AssemblyScript di proyek Anda?
