WebAssembly 高级应用

WebAssembly 高级应用

WebAssembly 已经成为前端性能优化的关键工具。

Rust + Wasm

优化计算密集型任务

// lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
    if n <= 1 { return n }
    
    let (mut a, mut b) = (0, 1);
    for _ in 2..=n {
        let temp = a + b;
        a = b;
        b = temp;
    }
    b
}

#[wasm_bindgen]
pub fn process_image(data: &mut [u8]) {
    // 图像处理逻辑
    for pixel in data.chunks_mut(4) {
        // 反转颜色
        pixel[0] = 255 - pixel[0]; // R
        pixel[1] = 255 - pixel[1]; // G
        pixel[2] = 255 - pixel[2]; // B
    }
}

JavaScript 调用

import init, { fibonacci, process_image } from './pkg/my_wasm.js'

async function main() {
  await init()
  
  // 高性能计算
  const result = fibonacci(40)
  console.log(`Fibonacci(40) = ${result}`)
  
  // 图像处理
  const imageData = new Uint8Array(width * height * 4)
  process_image(imageData)
}

内存共享

// JavaScript 和 Wasm 共享内存
const memory = new WebAssembly.Memory({ 
  initial: 256, 
  maximum: 256,
  shared: true  // SharedArrayBuffer
})

// 在 Worker 中使用
const worker = new Worker('worker.js')
worker.postMessage({ memory })

SIMD 优化

// 使用 SIMD 指令
#[cfg(target_arch = "wasm32")]
use std::arch::wasm32::*;

#[wasm_bindgen]
pub unsafe fn add_arrays_simd(a: &[f32], b: &[f32], result: &mut [f32]) {
    for i in (0..a.len()).step_by(4) {
        let va = v128_load(a.as_ptr().add(i) as *const v128)
        let vb = v128_load(b.as_ptr().add(i) as *const v128)
        let sum = f32x4_add(va, vb)
        v128_store(result.as_mut_ptr().add(i) as *mut v128, sum)
    }
}

线程并行

// Web Worker + Wasm 并行计算
// main.js
const workers = []
const numWorkers = navigator.hardwareConcurrency

for (let i = 0; i < numWorkers; i++) {
  workers.push(new Worker('worker.js'))
}

function parallelCompute(data) {
  const chunkSize = data.length / numWorkers
  
  return Promise.all(workers.map((worker, i) => {
    return new Promise(resolve => {
      worker.onmessage = e => resolve(e.data)
      worker.postMessage({
        start: i * chunkSize,
        end: (i + 1) * chunkSize,
        data: data.buffer
      })
    })
  }))
}

实际应用

视频处理

import { FFmpeg } from '@ffmpeg/ffmpeg'

const ffmpeg = new FFmpeg()
await ffmpeg.load()

// 在浏览器中处理视频
await ffmpeg.exec(['-i', 'input.mp4', '-vf', 'scale=1280:720', 'output.mp4'])

加密算法

import { sha256, aes_encrypt } from './crypto_wasm.js'

// 高性能加密
const hash = sha256(data)
const encrypted = aes_encrypt(data, key)

游戏物理

// 物理引擎运行在 Wasm
const physics = await PhysicsEngine.init()

function gameLoop() {
  physics.step(1/60)
  requestAnimationFrame(gameLoop)
}

性能对比

操作 JavaScript WebAssembly
图像处理 200ms 25ms
视频编码 5000ms 800ms
加密计算 150ms 15ms
物理模拟 50ms 5ms

最佳实践

  1. 识别性能瓶颈
  2. 仅对关键路径使用 Wasm
  3. 最小化 JS-Wasm 通信
  4. 使用 SIMD 和线程优化
  5. 合理使用共享内存