1) (data (i32.const 8) '1e000100010001e000~0l0i0b0/0r0t0/0t0l0s0f0.0t0s0') ... ;; Our global constants (not yet exported) (global $nBodyForces/FLOAT64ARRAY_ID i32 (i32.const 3)) (global $nBodyForces/G f64 (f64.const 6.674e-11)) (global $nBodyForces/bodySize i32 (i32.const 4)) (global $nBodyForces/forceSize i32 (i32.const 3)) ... ;; Memory management functions we’ll use in a minute (export 'memory' (memory

WebVR ตอนที่ 3: การปลดล็อกศักยภาพของ WebAssembly และ AssemblyScript

WebAssembly แน่นอน ไม่ การแทนที่ JavaScript เป็นภาษากลางของเว็บและของโลก

WebAssembly (Wasm แบบย่อ) เป็นรูปแบบคำสั่งไบนารีสำหรับเครื่องเสมือนที่ใช้สแต็ก Wasm ได้รับการออกแบบให้เป็นเป้าหมายแบบพกพาสำหรับการรวบรวมภาษาระดับสูงเช่น C / C ++ / Rust ทำให้สามารถปรับใช้บนเว็บสำหรับไคลเอ็นต์และเซิร์ฟเวอร์ได้” - WebAssembly.org

สิ่งสำคัญคือต้องแยกแยะว่า WebAssembly ไม่ใช่ภาษา WebAssembly ก็เหมือนกับไฟล์ '.exe' หรือดีกว่านั้นคือไฟล์ Java '.class' รวบรวมโดยนักพัฒนาเว็บจากภาษาอื่นจากนั้นดาวน์โหลดและเรียกใช้บนเบราว์เซอร์ของคุณ



WebAssembly ให้ JavaScript คุณลักษณะทั้งหมดที่เราต้องการยืมเป็นครั้งคราว แต่ไม่เคย จริงๆ อยากเป็นเจ้าของ เช่นเดียวกับการเช่าเรือหรือม้า WebAssembly ช่วยให้เราเดินทางไปยังภาษาอื่น ๆ โดยไม่ต้องเลือก 'วิถีชีวิตภาษา' ที่ฟุ่มเฟือย วิธีนี้ช่วยให้เว็บมุ่งเน้นไปที่สิ่งสำคัญเช่นการนำเสนอคุณลักษณะและปรับปรุงประสบการณ์ของผู้ใช้

มากกว่า 20 ภาษาที่รวบรวมไว้ใน WebAssembly: Rust, C / C ++, C # /. Net, Java, Python, Elixir, Go และ JavaScript แน่นอน

หากคุณจำแผนภาพสถาปัตยกรรมของการจำลองได้เราได้มอบหมายการจำลองทั้งหมดให้กับ nBodySimulator ดังนั้นจึงจัดการกับผู้ปฏิบัติงานบนเว็บ

แผนภาพสถาปัตยกรรมของการจำลอง

รูปที่ 1: สถาปัตยกรรมโดยรวม

หากคุณจำได้จากไฟล์ โพสต์แนะนำ , nBodySimulator มี step() เรียกฟังก์ชันทุกๆ 33ms step() ฟังก์ชันทำสิ่งเหล่านี้ - หมายเลขในแผนภาพด้านบน:

  1. nBodySimulator ของ calculateForces() โทร this.worker.postMessage() เพื่อเริ่มการคำนวณ
  2. คนงาน Wasm.js this.onmessage() รับข้อความ
  3. workerWasm.js พร้อมกันรัน nBodyForces.wasm’s nBodyForces() ฟังก์ชัน
  4. ตอบกลับ workerWasm.js โดยใช้ this.postMessage() ไปยังเธรดหลักด้วยกองกำลังใหม่
  5. เธรดหลัก this.worker.onMessage() จัดการข้อมูลที่ส่งคืนและการโทร
  6. nBodySimulator ของ applyForces() เพื่ออัปเดตตำแหน่งของร่างกาย
  7. ในที่สุด Visualizer ก็เขียนซ้ำ

เธรด UI เธรดผู้ปฏิบัติงานเว็บ

รูปที่ 2: ภายในฟังก์ชัน step () ของเครื่องจำลอง

ใน โพสต์ก่อนหน้านี้ เราได้สร้างผู้ปฏิบัติงานบนเว็บที่รวบรวมการคำนวณ WASM ของเรา วันนี้เรากำลังสร้างกล่องเล็ก ๆ ที่มีข้อความว่า“ WASM” และย้ายข้อมูลเข้าและออก

เพื่อความเรียบง่ายฉันเลือก AssemblyScript เป็นภาษาซอร์สโค้ดในการเขียนการคำนวณของเรา AssemblyScript เป็นชุดย่อยของ TypeScript ซึ่งเป็น JavaScript ที่พิมพ์ - ดังนั้นคุณจึงรู้อยู่แล้ว

ตัวอย่างเช่นฟังก์ชั่น AssemblyScript นี้จะคำนวณแรงโน้มถ่วงระหว่างสองส่วน: :f64 ใน someVar:f64 ทำเครื่องหมายตัวแปร someVar เป็น float สำหรับคอมไพเลอร์ โปรดจำไว้ว่ารหัสนี้ถูกคอมไพล์และรันในรันไทม์ที่แตกต่างจาก JavaScript อย่างสิ้นเชิง

// AssemblyScript - a TypeScript-like language that compiles to WebAssembly // src/assembly/nBodyForces.ts /** * Given two bodies, calculate the Force of Gravity, * then return as a 3-force vector (x, y, z) * * Sometimes, the force of gravity is: * * Fg = G * mA * mB / r^2 * * Given: * - Fg = Force of gravity * - r = sqrt ( dx + dy + dz) = straight line distance between 3d objects * - G = gravitational constant * - mA, mB = mass of objects * * Today, we're using better-gravity because better-gravity can calculate * force vectors without polar math (sin, cos, tan) * * Fbg = G * mA * mB * dr / r^3 // using dr as a 3-distance vector lets * // us project Fbg as a 3-force vector * * Given: * - Fbg = Force of better gravity * - dr = (dx, dy, dz) // a 3-distance vector * - dx = bodyB.x - bodyA.x * * Force of Better-Gravity: * * - Fbg = (Fx, Fy, Fz) = the change in force applied by gravity each * body's (x,y,z) over this time period * - Fbg = G * mA * mB * dr / r^3 * - dr = (dx, dy, dz) * - Fx = Gmm * dx / r3 * - Fy = Gmm * dy / r3 * - Fz = Gmm * dz / r3 * * From the parameters, return an array [fx, fy, fz] */ function twoBodyForces(xA: f64, yA: f64, zA: f64, mA: f64, xB: f64, yB: f64, zB: f64, mB: f64): f64[]

ฟังก์ชัน AssemblyScript นี้รับ (x, y, z, มวล) สำหรับสองร่างและส่งกลับอาร์เรย์ของสามลอยที่อธิบายถึงเวกเตอร์แรง (x, y, z) ที่ร่างกายใช้กับกันและกัน เราไม่สามารถเรียกฟังก์ชันนี้จาก JavaScript ได้เนื่องจาก JavaScript ไม่รู้ว่าจะหาได้จากที่ใด เราต้อง 'ส่งออก' เป็น JavaScript สิ่งนี้นำเราไปสู่ความท้าทายทางเทคนิคครั้งแรก

การนำเข้าและส่งออก WebAssembly

ใน ES6 เราคิดถึงการนำเข้าและส่งออกในโค้ด JavaScript และใช้เครื่องมือเช่น Rollup หรือ Webpack เพื่อสร้างโค้ดที่ทำงานในเบราว์เซอร์เดิมเพื่อจัดการ import และ require(). สิ่งนี้จะสร้างแผนผังการพึ่งพาจากบนลงล่างและเปิดใช้เทคโนโลยีที่ยอดเยี่ยมเช่น“ ต้นไม้สั่น ” และ การแยกรหัส .

ใน WebAssembly การนำเข้าและส่งออกจะบรรลุภารกิจที่แตกต่างจากการนำเข้า ES6 การนำเข้า / ส่งออก WebAssembly:

ในโค้ดด้านล่าง env.abort และ env.trace เป็นส่วนหนึ่งของสภาพแวดล้อมที่เราต้องจัดเตรียมให้กับโมดูล WebAssembly nBodyForces.logI และฟังก์ชั่นเพื่อนให้ข้อความการดีบักไปยังคอนโซล โปรดทราบว่าการส่งสตริงเข้า / ออกจาก WebAssembly นั้นไม่สำคัญเนื่องจากประเภทของ WebAssembly เท่านั้นคือ i32, i64, f32, f64 โดยมีการอ้างอิง i32 ไปยังหน่วยความจำเชิงเส้นนามธรรม

บันทึก: ตัวอย่างโค้ดเหล่านี้กำลังสลับไปมาระหว่างโค้ด JavaScript (ผู้ปฏิบัติงานบนเว็บ) และ AssemblyScript (โค้ด WASM)

// Web Worker JavaScript in workerWasm.js /** * When we instantiate the Wasm module, give it a context to work in: * nBodyForces: {} is a table of functions we can import into AssemblyScript. See top of nBodyForces.ts * env: {} describes the environment sent to the Wasm module as it's instantiated */ const importObj = { nBodyForces: { logI(data) { console.log('Log() - ' + data); }, logF(data) { console.log('Log() - ' + data); }, }, env: { abort(msg, file, line, column) { // wasm.__getString() is added by assemblyscript's loader: // https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader console.error('abort: (' + wasm.__getString(msg) + ') at ' + wasm.__getString(file) + ':' + line + ':' + column); }, trace(msg, n) { console.log('trace: ' + wasm.__getString(msg) + (n ? ' ' : '') + Array.prototype.slice.call(arguments, 2, 2 + n).join(', ')); } } }

ในโค้ด AssemblyScript ของเราเราสามารถนำเข้าฟังก์ชันเหล่านี้ให้เสร็จสิ้นได้ดังนี้:

// nBodyForces.ts declare function logI(data: i32): void declare function logF(data: f64): void

บันทึก : การยกเลิกและการติดตามจะถูกนำเข้าโดยอัตโนมัติ .

จาก AssemblyScript เราสามารถส่งออกอินเทอร์เฟซของเรา นี่คือค่าคงที่ที่ส่งออกบางส่วน:

// src/assembly/nBodyForces.ts // Gravitational constant. Any G could be used in a game. // This value is best for a scientific simulation. export const G: f64 = 6.674e-11; // for sizing and indexing arrays export const bodySize: i32 = 4 export const forceSize: i32 = 3

และนี่คือการส่งออกของ nBodyForces() ซึ่งเราจะเรียกจาก JavaScript เราส่งออกประเภท Float64Array ที่ด้านบนของไฟล์เพื่อให้เราสามารถใช้ตัวโหลด JavaScript ของ AssemblyScript ในผู้ปฏิบัติงานเว็บของเราเพื่อรับข้อมูล (ดูด้านล่าง):

// src/assembly/nBodyForces.ts export const FLOAT64ARRAY_ID = idof(); ... /** * Given N bodies with mass, in a 3d space, calculate the forces of gravity to be applied to each body. * * This function is exported to JavaScript, so only takes/returns numbers and arrays. * For N bodies, pass and array of 4N values (x,y,z,mass) and expect a 3N array of forces (x,y,z) * Those forces can be applied to the bodies mass to update its position in the simulation. * Calculate the 3-vector each unique pair of bodies applies to each other. * * 0 1 2 3 4 5 * 0 x x x x x * 1 x x x x * 2 x x x * 3 x x * 4 x * 5 * * Sum those forces together into an array of 3-vector x,y,z forces * * Return 0 on success */ export function nBodyForces(arrBodies: Float64Array): Float64Array { // Check inputs const numBodies: i32 = arrBodies.length / bodySize if (arrBodies.length % bodySize !== 0) trace('INVALID nBodyForces parameter. Chaos ensues...') // Create result array. This should be garbage collected later. let arrForces: Float64Array = new Float64Array(numBodies * forceSize) // For all bodies: for (let i: i32 = 0; i i for (let j: i32 = i + 1; j

WebAssembly Artifacts: .wasm และ .wat

เมื่อ AssemblyScript nBodyForces.ts ถูกรวบรวมลงใน WebAssembly nBodyForces.wasm ไบนารี่ นอกจากนี้ยังมีตัวเลือกในการสร้างเวอร์ชัน 'ข้อความ' ที่อธิบายคำแนะนำในไบนารี

WebAssembly Artifacts

รูปที่ 3: จำไว้ว่า AssemblyScript เป็นภาษา WebAssembly คือคอมไพเลอร์และรันไทม์

ภายใน nBodyForces.wat เราสามารถดูการนำเข้าและส่งออกเหล่านี้:

;; This is a comment in nBodyForces.wat (module ;; compiler defined types (type $FUNCSIG$iii (func (param i32 i32) (result i32))) … ;; Expected imports from JavaScript (import 'env' 'abort' (func $~lib/builtins/abort (param i32 i32 i32 i32))) (import 'env' 'trace' (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64))) ;; Memory section defining data constants like strings (memory $0 1) (data (i32.const 8) '1e000100010001e000~0l0i0b0/0r0t0/0t0l0s0f0.0t0s0') ... ;; Our global constants (not yet exported) (global $nBodyForces/FLOAT64ARRAY_ID i32 (i32.const 3)) (global $nBodyForces/G f64 (f64.const 6.674e-11)) (global $nBodyForces/bodySize i32 (i32.const 4)) (global $nBodyForces/forceSize i32 (i32.const 3)) ... ;; Memory management functions we’ll use in a minute (export 'memory' (memory $0)) (export '__alloc' (func $~lib/rt/tlsf/__alloc)) (export '__retain' (func $~lib/rt/pure/__retain)) (export '__release' (func $~lib/rt/pure/__release)) (export '__collect' (func $~lib/rt/pure/__collect)) (export '__rtti_base' (global $~lib/rt/__rtti_base)) ;; Finally our exported constants and function (export 'FLOAT64ARRAY_ID' (global $nBodyForces/FLOAT64ARRAY_ID)) (export 'G' (global $nBodyForces/G)) (export 'bodySize' (global $nBodyForces/bodySize)) (export 'forceSize' (global $nBodyForces/forceSize)) (export 'nBodyForces' (func $nBodyForces/nBodyForces)) ;; Implementation details ...

ตอนนี้เรามี nBodyForces.wasm ของเราแล้ว ไบนารีและผู้ปฏิบัติงานบนเว็บเพื่อเรียกใช้งาน เตรียมตัวให้พร้อมสำหรับการระเบิด! และการจัดการหน่วยความจำบาง!

ในการผสานรวมเราต้องส่งอาร์เรย์ตัวแปรของการลอยไปยัง WebAssembly และส่งคืนอาร์เรย์ตัวแปรของการลอยไปยัง JavaScript

ด้วยชนชั้นกลางจาวาสคริปต์ที่ไร้เดียงสาฉันตั้งเป้าที่จะส่งอาร์เรย์ขนาดตัวแปรที่ฉูดฉาดเหล่านี้เข้าและออกจากรันไทม์ประสิทธิภาพสูงข้ามแพลตฟอร์ม การส่งผ่านข้อมูลไปยัง / จาก WebAssembly เป็นปัญหาที่ไม่คาดคิดที่สุดในโครงการนี้

อย่างไรก็ตามด้วยความขอบคุณมากสำหรับไฟล์ การยกของหนักทำได้โดยทีม AssemblyScript เราสามารถใช้ 'ตัวโหลด' เพื่อช่วย:

// workerWasm.js - our web worker /** * AssemblyScript loader adds helpers for moving data to/from AssemblyScript. * Highly recommended */ const loader = require('assemblyscript/lib/loader')

require() หมายความว่าเราจำเป็นต้องใช้โมดูลบันเดิลเช่น Rollup หรือ Webpack สำหรับโครงการนี้ฉันเลือก Rollup เพื่อความเรียบง่ายและความยืดหยุ่นและไม่เคยมองย้อนกลับไป

โปรดจำไว้ว่าผู้ปฏิบัติงานบนเว็บของเราทำงานในเธรดแยกต่างหากและโดยพื้นฐานแล้วจะเป็น onmessage() ฟังก์ชันที่มี switch() คำให้การ.

loader สร้างโมดูล wasm ของเราด้วยฟังก์ชันการจัดการหน่วยความจำที่มีประโยชน์พิเศษ __retain() และ __release() จัดการการอ้างอิงการรวบรวมขยะในรันไทม์ของผู้ปฏิบัติงาน __allocArray() คัดลอกอาร์เรย์พารามิเตอร์ของเราไปยังหน่วยความจำของโมดูล wasm __getFloat64Array() คัดลอกอาร์เรย์ผลลัพธ์จากโมดูล wasm ไปยังรันไทม์ของผู้ปฏิบัติงาน

ตอนนี้เราสามารถ marshal float อาร์เรย์เข้าและออกจาก nBodyForces() และทำแบบจำลองของเราให้สมบูรณ์:

// workerWasm.js /** * Web workers listen for messages from the main thread. */ this.onmessage = function (evt) { // message from UI thread var msg = evt.data switch (msg.purpose) { // Message: Load new wasm module case 'wasmModule': // Instantiate the compiled module we were passed. wasm = loader.instantiate(msg.wasmModule, importObj) // Throws // Tell nBodySimulation.js we are ready this.postMessage({ purpose: 'wasmReady' }) return // Message: Given array of floats describing a system of bodies (x,y,x,mass), // calculate the Grav forces to be applied to each body case 'nBodyForces': if (!wasm) throw new Error('wasm not initialized') // Copy msg.arrBodies array into the wasm instance, increase GC count const dataRef = wasm.__retain(wasm.__allocArray(wasm.FLOAT64ARRAY_ID, msg.arrBodies)); // Do the calculations in this thread synchronously const resultRef = wasm.nBodyForces(dataRef); // Copy result array from the wasm instance to our javascript runtime const arrForces = wasm.__getFloat64Array(resultRef); // Decrease the GC count on dataRef from __retain() here, // and GC count from new Float64Array in wasm module wasm.__release(dataRef); wasm.__release(resultRef); // Message results back to main thread. // see nBodySimulation.js this.worker.onmessage return this.postMessage({ purpose: 'nBodyForces', arrForces }) } }

จากทั้งหมดที่เราได้เรียนรู้มาลองทบทวนผู้ปฏิบัติงานเว็บและการเดินทางของ WebAssembly กัน ยินดีต้อนรับสู่เบราว์เซอร์แบ็กเอนด์ใหม่ของเว็บ นี่คือลิงค์ไปยังโค้ดบน GitHub:

  1. รับ Index.html
  2. main.js
  3. nBodySimulator.js - ส่งข้อความไปยังผู้ปฏิบัติงานเว็บ
  4. คนงาน - เรียกใช้ฟังก์ชัน WebAssembly
  5. nBodyForces.ts - คำนวณและส่งคืนอาร์เรย์ของกองกำลัง
  6. คนงาน - ส่งผลลัพธ์กลับไปที่เธรดหลัก
  7. nBodySimulator.js - แก้ไขสัญญาสำหรับกองกำลัง
  8. nBodySimulator.js - จากนั้นใช้กองกำลังกับร่างกายและบอกให้ผู้สร้างภาพวาดภาพ

เริ่มต้นการแสดงด้วยการสร้าง nBodyVisualizer.js! โพสต์ถัดไปของเราจะสร้าง Visualizer โดยใช้ Canvas API และโพสต์สุดท้ายจะสรุปด้วย WebVR และ Aframe

ที่เกี่ยวข้อง: WebAssembly / Rust Tutorial: Pitch-perfect Audio Processing

ทำความเข้าใจพื้นฐาน

WebAssembly สามารถแทนที่ JavaScript ได้หรือไม่

WebAssembly ไม่ใช่ภาษาดังนั้นจึงไม่สามารถแทนที่ JavaScript ได้ นอกจากนี้การพัฒนาคุณสมบัติและประสบการณ์ของผู้ใช้ใน WebAssembly ยังมีประสิทธิภาพน้อยกว่า

เหตุใด WebAssembly จึงเร็วขึ้น

WebAssembly เร็วกว่าเพราะทำงานน้อยลงและได้รับการออกแบบมาเพื่อประสิทธิภาพแทนการใช้งานของนักพัฒนา

สามารถคอมไพล์ JavaScript ไปยัง WebAssembly ได้หรือไม่?

ใช่ AssemblyScript คอมไพล์เป็น WebAssembly และให้ความรู้สึกเหมือน typescript

)) (export '__alloc' (func $~lib/rt/tlsf/__alloc)) (export '__retain' (func $~lib/rt/pure/__retain)) (export '__release' (func $~lib/rt/pure/__release)) (export '__collect' (func $~lib/rt/pure/__collect)) (export '__rtti_base' (global $~lib/rt/__rtti_base)) ;; Finally our exported constants and function (export 'FLOAT64ARRAY_ID' (global $nBodyForces/FLOAT64ARRAY_ID)) (export 'G' (global $nBodyForces/G)) (export 'bodySize' (global $nBodyForces/bodySize)) (export 'forceSize' (global $nBodyForces/forceSize)) (export 'nBodyForces' (func $nBodyForces/nBodyForces)) ;; Implementation details ...

ตอนนี้เรามี nBodyForces.wasm ของเราแล้ว ไบนารีและผู้ปฏิบัติงานบนเว็บเพื่อเรียกใช้งาน เตรียมตัวให้พร้อมสำหรับการระเบิด! และการจัดการหน่วยความจำบาง!

ในการผสานรวมเราต้องส่งอาร์เรย์ตัวแปรของการลอยไปยัง WebAssembly และส่งคืนอาร์เรย์ตัวแปรของการลอยไปยัง JavaScript

ด้วยชนชั้นกลางจาวาสคริปต์ที่ไร้เดียงสาฉันตั้งเป้าที่จะส่งอาร์เรย์ขนาดตัวแปรที่ฉูดฉาดเหล่านี้เข้าและออกจากรันไทม์ประสิทธิภาพสูงข้ามแพลตฟอร์ม การส่งผ่านข้อมูลไปยัง / จาก WebAssembly เป็นปัญหาที่ไม่คาดคิดที่สุดในโครงการนี้

อย่างไรก็ตามด้วยความขอบคุณมากสำหรับไฟล์ การยกของหนักทำได้โดยทีม AssemblyScript เราสามารถใช้ 'ตัวโหลด' เพื่อช่วย:

// workerWasm.js - our web worker /** * AssemblyScript loader adds helpers for moving data to/from AssemblyScript. * Highly recommended */ const loader = require('assemblyscript/lib/loader')

require() หมายความว่าเราจำเป็นต้องใช้โมดูลบันเดิลเช่น Rollup หรือ Webpack สำหรับโครงการนี้ฉันเลือก Rollup เพื่อความเรียบง่ายและความยืดหยุ่นและไม่เคยมองย้อนกลับไป

bootstrap คืออะไรในการพัฒนาเว็บ

โปรดจำไว้ว่าผู้ปฏิบัติงานบนเว็บของเราทำงานในเธรดแยกต่างหากและโดยพื้นฐานแล้วจะเป็น onmessage() ฟังก์ชันที่มี switch() คำให้การ.

loader สร้างโมดูล wasm ของเราด้วยฟังก์ชันการจัดการหน่วยความจำที่มีประโยชน์พิเศษ __retain() และ __release() จัดการการอ้างอิงการรวบรวมขยะในรันไทม์ของผู้ปฏิบัติงาน __allocArray() คัดลอกอาร์เรย์พารามิเตอร์ของเราไปยังหน่วยความจำของโมดูล wasm __getFloat64Array() คัดลอกอาร์เรย์ผลลัพธ์จากโมดูล wasm ไปยังรันไทม์ของผู้ปฏิบัติงาน

ตอนนี้เราสามารถ marshal float อาร์เรย์เข้าและออกจาก nBodyForces() และทำแบบจำลองของเราให้สมบูรณ์:

// workerWasm.js /** * Web workers listen for messages from the main thread. */ this.onmessage = function (evt) { // message from UI thread var msg = evt.data switch (msg.purpose) { // Message: Load new wasm module case 'wasmModule': // Instantiate the compiled module we were passed. wasm = loader.instantiate(msg.wasmModule, importObj) // Throws // Tell nBodySimulation.js we are ready this.postMessage({ purpose: 'wasmReady' }) return // Message: Given array of floats describing a system of bodies (x,y,x,mass), // calculate the Grav forces to be applied to each body case 'nBodyForces': if (!wasm) throw new Error('wasm not initialized') // Copy msg.arrBodies array into the wasm instance, increase GC count const dataRef = wasm.__retain(wasm.__allocArray(wasm.FLOAT64ARRAY_ID, msg.arrBodies)); // Do the calculations in this thread synchronously const resultRef = wasm.nBodyForces(dataRef); // Copy result array from the wasm instance to our javascript runtime const arrForces = wasm.__getFloat64Array(resultRef); // Decrease the GC count on dataRef from __retain() here, // and GC count from new Float64Array in wasm module wasm.__release(dataRef); wasm.__release(resultRef); // Message results back to main thread. // see nBodySimulation.js this.worker.onmessage return this.postMessage({ purpose: 'nBodyForces', arrForces }) } }

จากทั้งหมดที่เราได้เรียนรู้มาลองทบทวนผู้ปฏิบัติงานเว็บและการเดินทางของ WebAssembly กัน ยินดีต้อนรับสู่เบราว์เซอร์แบ็กเอนด์ใหม่ของเว็บ นี่คือลิงค์ไปยังโค้ดบน GitHub:

  1. รับ Index.html
  2. main.js
  3. nBodySimulator.js - ส่งข้อความไปยังผู้ปฏิบัติงานเว็บ
  4. คนงาน - เรียกใช้ฟังก์ชัน WebAssembly
  5. nBodyForces.ts - คำนวณและส่งคืนอาร์เรย์ของกองกำลัง
  6. คนงาน - ส่งผลลัพธ์กลับไปที่เธรดหลัก
  7. nBodySimulator.js - แก้ไขสัญญาสำหรับกองกำลัง
  8. nBodySimulator.js - จากนั้นใช้กองกำลังกับร่างกายและบอกให้ผู้สร้างภาพวาดภาพ

เริ่มต้นการแสดงด้วยการสร้าง nBodyVisualizer.js! โพสต์ถัดไปของเราจะสร้าง Visualizer โดยใช้ Canvas API และโพสต์สุดท้ายจะสรุปด้วย WebVR และ Aframe

ที่เกี่ยวข้อง: WebAssembly / Rust Tutorial: Pitch-perfect Audio Processing

ทำความเข้าใจพื้นฐาน

WebAssembly สามารถแทนที่ JavaScript ได้หรือไม่

WebAssembly ไม่ใช่ภาษาดังนั้นจึงไม่สามารถแทนที่ JavaScript ได้ นอกจากนี้การพัฒนาคุณสมบัติและประสบการณ์ของผู้ใช้ใน WebAssembly ยังมีประสิทธิภาพน้อยกว่า

เหตุใด WebAssembly จึงเร็วขึ้น

WebAssembly เร็วกว่าเพราะทำงานน้อยลงและได้รับการออกแบบมาเพื่อประสิทธิภาพแทนการใช้งานของนักพัฒนา

สามารถคอมไพล์ JavaScript ไปยัง WebAssembly ได้หรือไม่?

ใช่ AssemblyScript คอมไพล์เป็น WebAssembly และให้ความรู้สึกเหมือน typescript