WebAssembly trong Next.js 15: Tăng tốc app với Wasm
WebAssembly giúp chạy code compiled (Rust, C++) trực tiếp trong browser với tốc độ gần native. Hướng dẫn tích hợp Wasm vào Next.js 15 — từ video compression với FFmpeg đến custom .wasm modules, kèm benchmark thực tế.
Wasm trong trình duyệt: Tăng tốc Next.js app với WebAssembly
JavaScript nhanh — nhưng không phải lúc nào cũng đủ nhanh. Khi cần xử lý video, image compression, crypto operations, hay parsing file lớn trên client, bạn cần WebAssembly (Wasm). Đây là công nghệ giúp bạn chạy code compiled (C, C++, Rust, Go) trực tiếp trong browser với performance gần native.
Wasm là gì và khi nào dùng?
WebAssembly là binary format chạy được trong browser sandbox, song song với JavaScript. Browser hiện đại (Chrome, Firefox, Safari, Edge) đều hỗ trợ. Wasm không replace JavaScript — nó complement. Dùng JS cho UI logic, DOM manipulation; dùng Wasm cho heavy computation.
Các use case phù hợp:
- Image/video processing (resize, compress, filter) trên client
- Cryptography (hashing, encryption) — nhanh hơn JS thuần 10-20x
- PDF parsing, ZIP compression/decompression
- Game engines, physics simulations
- Machine learning inference (ONNX Runtime Web)
Dùng thư viện Wasm có sẵn — cách nhanh nhất
Không cần tự viết Rust hay C++. Nhiều thư viện Wasm đã được publish lên npm. Ví dụ với @ffmpeg/ffmpeg để transcode video:
// app/components/VideoCompressor.tsx
'use client'
import { useState } from 'react'
import { FFmpeg } from '@ffmpeg/ffmpeg'
import { fetchFile, toBlobURL } from '@ffmpeg/util'
export function VideoCompressor() {
const [progress, setProgress] = useState(0)
const [outputUrl, setOutputUrl] = useState('')
async function compress(file: File) {
const ffmpeg = new FFmpeg()
// Load Wasm binary (chỉ load 1 lần)
const baseURL = 'https://unpkg.com/@ffmpeg/core@0.12.6/dist/umd'
await ffmpeg.load({
coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'),
})
ffmpeg.on('progress', ({ progress }) => {
setProgress(Math.round(progress * 100))
})
// Write file vào Wasm virtual filesystem
await ffmpeg.writeFile('input.mp4', await fetchFile(file))
// Transcode với quality thấp hơn
await ffmpeg.exec(['-i', 'input.mp4', '-crf', '28', 'output.mp4'])
const data = await ffmpeg.readFile('output.mp4')
const blob = new Blob([data], { type: 'video/mp4' })
setOutputUrl(URL.createObjectURL(blob))
}
return (
<div>
<input type="file" accept="video/*" onChange={e => compress(e.target.files![0])} />
{progress > 0 && <p>Progress: {progress}%</p>}
{outputUrl && <a href={outputUrl} download>Tải video đã nén</a>}
</div>
)
}
Tích hợp Wasm vào Next.js 15
Next.js 15 hỗ trợ Wasm natively qua webpack config. Thêm vào next.config.ts:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
webpack: (config) => {
// Enable Wasm support
config.experiments = {
...config.experiments,
asyncWebAssembly: true,
layers: true,
}
return config
},
}
export default nextConfig
Sau đó bạn có thể import file .wasm trực tiếp:
// Trong component (client-side only)
const wasmModule = await import('../lib/my-module.wasm')
const result = wasmModule.process_data(inputBuffer)
Performance thực tế
Benchmark nhanh: SHA-256 hash 10MB data trên browser:
- JavaScript thuần (SubtleCrypto): ~45ms
- Wasm (sha2 crate từ Rust): ~8ms
- Cải thiện: ~5.6x faster
Con số này còn ấn tượng hơn với workload compute-heavy như video encoding hay image convolution.
Những điều cần lưu ý
- Load time: File
.wasmcần download lần đầu. Sử dụng caching headers tốt và lazy load. - Memory: Wasm dùng linear memory, không có garbage collector. Cần free memory thủ công nếu dùng Rust/C.
- Debugging: Khó debug hơn JS. Source maps cho Wasm đã có nhưng tooling chưa hoàn hảo.
- Bundle size: Wasm binary thường nhỏ hơn equivalent JS code. Đây là điểm cộng.
Tip cho Next.js: Luôn wrap Wasm-heavy operations trong'use client'components và dùngdynamic importvớissr: false. Wasm không chạy được trong Node.js server environment của Next.js mà không có cấu hình đặc biệt.
Kết luận
WebAssembly mở ra cánh cửa để đưa những tác vụ nặng lên client, giảm tải server và cải thiện user experience đáng kể. Với Next.js 15 hỗ trợ native, không còn lý do gì để không thử Wasm trong project tiếp theo của bạn — đặc biệt khi có các use case như image processing hay encryption.
Admin
Bình luận (0)
Đăng nhập để bình luận
Chưa có bình luận nào. Hãy là người đầu tiên!