WebAssembly(简称wasm)是一种新的二进制指令格式,可以在现代Web浏览器中运行,提供接近原生的性能。
东巴文(db-w.cn) 认为:WebAssembly是Web技术的重大突破,它允许使用C/C++、Rust等语言编写高性能Web应用,为计算密集型任务提供了新的解决方案,是Web平台的重要补充。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebAssembly概述 - 东巴文</title>
<style>
body {
font-family: 'Segoe UI', sans-serif;
padding: 20px;
background: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 10px;
}
h1 {
color: #667eea;
margin-bottom: 20px;
}
h2 {
color: #764ba2;
margin: 30px 0 15px;
border-left: 4px solid #764ba2;
padding-left: 15px;
}
.wasm-demo {
background: #f8f9fa;
padding: 20px;
border: 2px solid #ddd;
margin: 15px 0;
border-radius: 10px;
}
.wasm-demo h3 {
color: #667eea;
margin-bottom: 10px;
}
.feature-list {
list-style: none;
padding: 0;
}
.feature-list li {
padding: 8px 0;
border-bottom: 1px solid #eee;
}
.feature-list li:before {
content: "✓ ";
color: #667eea;
font-weight: bold;
}
.comparison-table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.comparison-table th,
.comparison-table td {
padding: 12px;
text-align: left;
border: 1px solid #ddd;
}
.comparison-table th {
background: #667eea;
color: white;
}
</style>
</head>
<body>
<div class="container">
<h1>WebAssembly概述</h1>
<h2>什么是WebAssembly</h2>
<div class="wasm-demo">
<h3>核心概念</h3>
<p>WebAssembly是一种新的二进制指令格式,可以在现代Web浏览器中运行。它设计为一种可移植、高效的Web编译目标,使各种编程语言能够在Web上运行。</p>
<ul class="feature-list">
<li><strong>高性能:</strong> 接近原生的执行速度</li>
<li><strong>可移植:</strong> 在所有现代浏览器中运行</li>
<li><strong>安全:</strong> 在沙箱环境中执行</li>
<li><strong>紧凑:</strong> 二进制格式,文件体积小</li>
<li><strong>兼容:</strong> 与JavaScript共存</li>
<li><strong>开放:</strong> W3C标准,开放Web平台的一部分</li>
</ul>
</div>
<h2>WebAssembly vs JavaScript</h2>
<table class="comparison-table">
<thead>
<tr>
<th>特性</th>
<th>WebAssembly</th>
<th>JavaScript</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>格式</strong></td>
<td>二进制</td>
<td>文本</td>
</tr>
<tr>
<td><strong>性能</strong></td>
<td>接近原生</td>
<td>JIT编译优化</td>
</tr>
<tr>
<td><strong>语言支持</strong></td>
<td>C/C++, Rust, Go等</td>
<td>JavaScript, TypeScript</td>
</tr>
<tr>
<td><strong>加载速度</strong></td>
<td>快(二进制解析)</td>
<td>慢(文本解析)</td>
</tr>
<tr>
<td><strong>内存管理</strong></td>
<td>手动管理</td>
<td>垃圾回收</td>
</tr>
<tr>
<td><strong>适用场景</strong></td>
<td>计算密集型任务</td>
<td>UI交互,DOM操作</td>
</tr>
</tbody>
</table>
<h2>WebAssembly应用场景</h2>
<div class="wasm-demo">
<h3>典型应用</h3>
<div style="background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 5px; margin: 10px 0;">
<pre>
1. 图像/视频处理
- 图像编辑器(Photopea)
- 视频编解码
- 图像压缩
2. 游戏
- 3D游戏引擎(Unity, Unreal)
- 游戏模拟器
- Web游戏
3. 科学计算
- 数值计算
- 数据可视化
- 模拟仿真
4. 加密
- 加密算法
- 区块链应用
- 安全计算
5. 音频处理
- 音频编解码
- 音频效果器
- 音乐合成
6. CAD/建模
- 3D建模工具
- CAD应用
- 建筑设计
7. AI/机器学习
- 模型推理
- 图像识别
- 自然语言处理
</pre>
</div>
</div>
<h2>WebAssembly示例</h2>
<div class="wasm-demo">
<h3>基本使用</h3>
<div style="background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 5px; margin: 10px 0;">
<pre>
// 加载WebAssembly模块
WebAssembly.instantiateStreaming(fetch('simple.wasm'))
.then(results => {
// 调用导出的函数
const add = results.instance.exports.add;
const result = add(10, 20);
console.log('10 + 20 =', result); // 30
});
// 或使用更通用的方式
fetch('simple.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
.then(results => {
const instance = results.instance;
const add = instance.exports.add;
console.log(add(5, 3)); // 8
});
</pre>
</div>
</div>
<div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
<strong>东巴文提示:</strong>WebAssembly是Web平台的重要补充,它为计算密集型任务提供了高性能解决方案。掌握WebAssembly,能将C/C++、Rust等语言的优势带到Web平台,扩展Web应用的能力边界。
</div>
</div>
</body>
</html>
Emscripten是将C/C++代码编译为WebAssembly的工具链,是最成熟的WebAssembly编译器。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Emscripten - 东巴文</title>
<style>
body {
font-family: 'Segoe UI', sans-serif;
padding: 20px;
background: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 10px;
}
h1 {
color: #667eea;
margin-bottom: 20px;
}
h2 {
color: #764ba2;
margin: 30px 0 15px;
border-left: 4px solid #764ba2;
padding-left: 15px;
}
.emscripten-demo {
background: #f8f9fa;
padding: 20px;
border: 2px solid #ddd;
margin: 15px 0;
border-radius: 10px;
}
.emscripten-demo h3 {
color: #667eea;
margin-bottom: 10px;
}
.code-block {
background: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
margin: 10px 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Emscripten</h1>
<h2>安装Emscripten</h2>
<div class="emscripten-demo">
<h3>安装步骤</h3>
<div class="code-block">
<pre>
# 使用emsdk安装
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
# 安装最新版本
./emsdk install latest
# 激活最新版本
./emsdk activate latest
# 配置环境变量
source ./emsdk_env.sh
# 验证安装
emcc --version
</pre>
</div>
</div>
<h2>编译C代码</h2>
<div class="emscripten-demo">
<h3>简单示例</h3>
<div class="code-block">
<pre>
// hello.c
#include <stdio.h>
#include <emscripten.h>
int main() {
printf("Hello, WebAssembly!\n");
return 0;
}
// 导出函数供JavaScript调用
EMSCRIPTEN_KEEPALIVE
int add(int a, int b) {
return a + b;
}
EMSCRIPTEN_KEEPALIVE
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
</pre>
</div>
<div class="code-block">
<pre>
# 编译为WebAssembly
emcc hello.c -o hello.html
# 或编译为wasm和js文件
emcc hello.c -o hello.js
# 常用编译选项
emcc hello.c \
-o hello.html \
-s WASM=1 \ # 生成WebAssembly
-s EXPORTED_FUNCTIONS="['_add', '_factorial']" \ # 导出函数
-s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" \ # 导出运行时方法
-s MODULARIZE=1 \ # 模块化输出
-s EXPORT_NAME="createModule" \ # 模块名称
-O3 # 优化级别
</pre>
</div>
</div>
<h2>在JavaScript中调用</h2>
<div class="emscripten-demo">
<h3>调用导出函数</h3>
<div class="code-block">
<pre>
// 加载模块
Module.onRuntimeInitialized = () => {
// 使用ccall调用
const result = Module.ccall(
'add', // 函数名
'number', // 返回类型
['number', 'number'], // 参数类型
[10, 20] // 参数值
);
console.log('10 + 20 =', result); // 30
// 使用cwrap包装函数
const add = Module.cwrap('add', 'number', ['number', 'number']);
console.log('5 + 3 =', add(5, 3)); // 8
const factorial = Module.cwrap('factorial', 'number', ['number']);
console.log('5! =', factorial(5)); // 120
// 直接调用(需要下划线前缀)
console.log('7 + 8 =', Module._add(7, 8)); // 15
};
</pre>
</div>
</div>
<h2>处理字符串</h2>
<div class="emscripten-demo">
<h3>字符串传递</h3>
<div class="code-block">
<pre>
// string.c
#include <stdio.h>
#include <string.h>
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
const char* greet(const char* name) {
static char buffer[256];
sprintf(buffer, "Hello, %s!", name);
return buffer;
}
EMSCRIPTEN_KEEPALIVE
int stringLength(const char* str) {
return strlen(str);
}
</pre>
</div>
<div class="code-block">
<pre>
// JavaScript调用
const greet = Module.cwrap('greet', 'string', ['string']);
const message = greet('WebAssembly');
console.log(message); // "Hello, WebAssembly!"
const stringLength = Module.cwrap('stringLength', 'number', ['string']);
console.log(stringLength('Hello')); // 5
// 手动处理字符串
function passString(str) {
// 分配内存
const ptr = Module.allocate(
Module.intArrayFromString(str),
Module.ALLOC_NORMAL
);
// 调用函数
const resultPtr = Module._greet(ptr);
// 读取返回的字符串
const result = Module.UTF8ToString(resultPtr);
// 释放内存
Module._free(ptr);
return result;
}
</pre>
</div>
</div>
<h2>处理数组</h2>
<div class="emscripten-demo">
<h3>数组传递</h3>
<div class="code-block">
<pre>
// array.c
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int sumArray(int* arr, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
EMSCRIPTEN_KEEPALIVE
void doubleArray(int* arr, int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2;
}
}
</pre>
</div>
<div class="code-block">
<pre>
// JavaScript调用
const sumArray = Module.cwrap('sumArray', 'number', ['number', 'number']);
const doubleArray = Module.cwrap('doubleArray', null, ['number', 'number']);
// 传递数组
const arr = [1, 2, 3, 4, 5];
const size = arr.length;
// 分配内存
const ptr = Module._malloc(size * 4); // int = 4 bytes
// 写入数组到内存
Module.HEAP32.set(arr, ptr / 4);
// 调用函数
const sum = sumArray(ptr, size);
console.log('Sum:', sum); // 15
// 修改数组
doubleArray(ptr, size);
// 读取修改后的数组
const doubled = Module.HEAP32.subarray(ptr / 4, ptr / 4 + size);
console.log('Doubled:', Array.from(doubled)); // [2, 4, 6, 8, 10]
// 释放内存
Module._free(ptr);
</pre>
</div>
</div>
<div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
<strong>东巴文提示:</strong>Emscripten是将C/C++代码移植到Web的最成熟工具。掌握Emscripten的编译选项、函数导出、数据传递,能将现有的C/C++库高效地移植到Web平台。
</div>
</div>
</body>
</html>
WebAssembly模块可以通过多种方式加载和实例化。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>wasm模块加载 - 东巴文</title>
<style>
body {
font-family: 'Segoe UI', sans-serif;
padding: 20px;
background: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 10px;
}
h1 {
color: #667eea;
margin-bottom: 20px;
}
h2 {
color: #764ba2;
margin: 30px 0 15px;
border-left: 4px solid #764ba2;
padding-left: 15px;
}
.loading-demo {
background: #f8f9fa;
padding: 20px;
border: 2px solid #ddd;
margin: 15px 0;
border-radius: 10px;
}
.loading-demo h3 {
color: #667eea;
margin-bottom: 10px;
}
.code-block {
background: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
margin: 10px 0;
}
</style>
</head>
<body>
<div class="container">
<h1>wasm模块加载</h1>
<h2>加载方式</h2>
<div class="loading-demo">
<h3>1. instantiateStreaming</h3>
<div class="code-block">
<pre>
// 最推荐的加载方式
WebAssembly.instantiateStreaming(fetch('module.wasm'))
.then(results => {
const instance = results.instance;
const exports = instance.exports;
// 调用导出的函数
console.log(exports.add(10, 20));
})
.catch(error => {
console.error('加载失败:', error);
});
// 带导入对象的加载
const importObject = {
env: {
memory: new WebAssembly.Memory({ initial: 256 }),
table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
},
imports: {
imported_func: arg => console.log('Imported:', arg)
}
};
WebAssembly.instantiateStreaming(fetch('module.wasm'), importObject)
.then(results => {
const instance = results.instance;
// 使用实例
});
</pre>
</div>
</div>
<div class="loading-demo">
<h3>2. 使用ArrayBuffer</h3>
<div class="code-block">
<pre>
// 兼容性更好的方式
fetch('module.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes, importObject))
.then(results => {
const instance = results.instance;
const module = results.module;
// 使用实例
console.log(instance.exports.add(5, 3));
});
// 分步加载
fetch('module.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.compile(bytes))
.then(module => {
// 可以多次实例化
const instance1 = new WebAssembly.Instance(module, importObject);
const instance2 = new WebAssembly.Instance(module, importObject);
return { module, instance: instance1 };
});
</pre>
</div>
</div>
<div class="loading-demo">
<h3>3. 动态导入</h3>
<div class="code-block">
<pre>
// ES模块方式(实验性)
const module = await import('./module.wasm');
console.log(module.add(10, 20));
// 或使用script标签
<script type="module">
import init, { add, subtract } from './pkg/my_module.js';
async function run() {
// 初始化模块
const module = await init();
// 调用函数
console.log(add(10, 5)); // 15
console.log(subtract(10, 5)); // 5
}
run();
</script>
</pre>
</div>
</div>
<h2>WebAssembly JavaScript API</h2>
<div class="loading-demo">
<h3>核心对象</h3>
<div class="code-block">
<pre>
// 1. WebAssembly.Module
// 编译后的WebAssembly模块
const module = await WebAssembly.compile(bytes);
// 检查模块
console.log(WebAssembly.Module.customSections(module, 'name'));
console.log(WebAssembly.Module.exports(module));
console.log(WebAssembly.Module.imports(module));
// 2. WebAssembly.Instance
// 模块的实例
const instance = new WebAssembly.Instance(module, importObject);
// 访问导出
const exports = instance.exports;
console.log(exports.add); // 函数
console.log(exports.memory); // 内存
console.log(exports.table); // 表
// 3. WebAssembly.Memory
// 线性内存
const memory = new WebAssembly.Memory({
initial: 256, // 初始页数(每页64KB)
maximum: 1024 // 最大页数
});
// 访问内存
const buffer = memory.buffer;
const view = new Int32Array(buffer);
// 4. WebAssembly.Table
// 函数表
const table = new WebAssembly.Table({
initial: 2,
element: 'anyfunc'
});
// 设置函数
table.set(0, exports.func1);
table.set(1, exports.func2);
// 调用
table.get(0)();
// 5. WebAssembly.Global
// 全局变量
const global = new WebAssembly.Global({ value: 'i32', mutable: true }, 0);
console.log(global.value); // 0
global.value = 10;
console.log(global.value); // 10
</pre>
</div>
</div>
<h2>错误处理</h2>
<div class="loading-demo">
<h3>捕获错误</h3>
<div class="code-block">
<pre>
// WebAssembly错误类型
try {
const result = WebAssembly.compile(invalidBytes);
} catch (e) {
if (e instanceof WebAssembly.CompileError) {
console.error('编译错误:', e.message);
} else if (e instanceof WebAssembly.LinkError) {
console.error('链接错误:', e.message);
} else if (e instanceof WebAssembly.RuntimeError) {
console.error('运行时错误:', e.message);
}
}
// 完整的错误处理
async function loadWasm(url, importObject) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const instance = await WebAssembly.instantiateStreaming(
response,
importObject
);
return instance.instance.exports;
} catch (error) {
console.error('加载WebAssembly失败:', error);
// 降级处理
return fallbackImplementation();
}
}
function fallbackImplementation() {
// JavaScript降级实现
return {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
}
</pre>
</div>
</div>
<div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
<strong>东巴文提示:</strong>掌握WebAssembly的加载方式和JavaScript API,能灵活地在Web应用中集成WebAssembly模块。注意错误处理和降级方案,确保应用的健壮性。
</div>
</div>
</body>
</html>
JavaScript和WebAssembly可以相互调用,共享内存。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript与wasm交互 - 东巴文</title>
<style>
body {
font-family: 'Segoe UI', sans-serif;
padding: 20px;
background: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 10px;
}
h1 {
color: #667eea;
margin-bottom: 20px;
}
h2 {
color: #764ba2;
margin: 30px 0 15px;
border-left: 4px solid #764ba2;
padding-left: 15px;
}
.interaction-demo {
background: #f8f9fa;
padding: 20px;
border: 2px solid #ddd;
margin: 15px 0;
border-radius: 10px;
}
.interaction-demo h3 {
color: #667eea;
margin-bottom: 10px;
}
.code-block {
background: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
margin: 10px 0;
}
</style>
</head>
<body>
<div class="container">
<h1>JavaScript与wasm交互</h1>
<h2>JavaScript调用wasm</h2>
<div class="interaction-demo">
<h3>基本调用</h3>
<div class="code-block">
<pre>
// C代码
int add(int a, int b) {
return a + b;
}
// JavaScript调用
const result = instance.exports.add(10, 20);
console.log(result); // 30
// 复杂类型
// C代码
void processArray(int* data, int length) {
for (int i = 0; i < length; i++) {
data[i] *= 2;
}
}
// JavaScript调用
const memory = instance.exports.memory;
const processArray = instance.exports.processArray;
// 创建数组
const data = new Int32Array([1, 2, 3, 4, 5]);
const length = data.length;
// 在wasm内存中分配空间
const ptr = instance.exports.alloc(length * 4);
// 复制数据到wasm内存
const wasmArray = new Int32Array(memory.buffer, ptr, length);
wasmArray.set(data);
// 调用wasm函数
processArray(ptr, length);
// 读取结果
console.log(Array.from(wasmArray)); // [2, 4, 6, 8, 10]
// 释放内存
instance.exports.dealloc(ptr, length * 4);
</pre>
</div>
</div>
<h2>wasm调用JavaScript</h2>
<div class="interaction-demo">
<h3>导入JavaScript函数</h3>
<div class="code-block">
<pre>
// 导入对象
const importObject = {
env: {
// 导入console.log
js_console_log: (ptr, length) => {
const memory = instance.exports.memory;
const buffer = new Uint8Array(memory.buffer, ptr, length);
const str = new TextDecoder().decode(buffer);
console.log(str);
},
// 导入数学函数
js_random: () => Math.random(),
// 导入DOM操作
js_set_title: (ptr, length) => {
const memory = instance.exports.memory;
const buffer = new Uint8Array(memory.buffer, ptr, length);
const title = new TextDecoder().decode(buffer);
document.title = title;
},
// 导入回调
js_callback: (data) => {
console.log('Callback from wasm:', data);
}
}
};
// 加载wasm
const instance = await WebAssembly.instantiateStreaming(
fetch('module.wasm'),
importObject
).then(results => results.instance);
// C代码中使用
/*
#include <emscripten.h>
extern void js_console_log(const char* str, int length);
extern double js_random();
extern void js_set_title(const char* title, int length);
void log_message() {
const char* msg = "Hello from WebAssembly!";
js_console_log(msg, strlen(msg));
}
double get_random() {
return js_random();
}
void change_title() {
const char* title = "New Title";
js_set_title(title, strlen(title));
}
*/
</pre>
</div>
</div>
<h2>共享内存</h2>
<div class="interaction-demo">
<h3>内存共享</h3>
<div class="code-block">
<pre>
// 创建共享内存
const memory = new WebAssembly.Memory({
initial: 256,
maximum: 1024,
shared: true // SharedArrayBuffer
});
const importObject = {
env: { memory }
};
// 加载wasm
const instance = await WebAssembly.instantiateStreaming(
fetch('module.wasm'),
importObject
).then(results => results.instance);
// JavaScript和wasm共享内存
const buffer = memory.buffer;
const view = new Int32Array(buffer);
// JavaScript写入
view[0] = 100;
view[1] = 200;
// wasm读取和修改
instance.exports.process_shared_memory();
// JavaScript读取结果
console.log(view[0], view[1]);
// 多线程共享(需要SharedArrayBuffer)
if (typeof SharedArrayBuffer !== 'undefined') {
const sharedMemory = new WebAssembly.Memory({
initial: 256,
maximum: 1024,
shared: true
});
// 可以在多个Worker中共享
const worker = new Worker('worker.js');
worker.postMessage({ memory: sharedMemory });
}
</pre>
</div>
</div>
<h2>函数表</h2>
<div class="interaction-demo">
<h3>间接调用</h3>
<div class="code-block">
<pre>
// 创建函数表
const table = new WebAssembly.Table({
initial: 10,
element: 'anyfunc'
});
const importObject = {
env: {
table,
memory: new WebAssembly.Memory({ initial: 256 })
}
};
// 加载wasm
const instance = await WebAssembly.instantiateStreaming(
fetch('module.wasm'),
importObject
).then(results => results.instance);
// wasm填充函数表
instance.exports.fill_table();
// JavaScript调用函数表中的函数
const func0 = table.get(0);
const func1 = table.get(1);
console.log(func0(10, 5)); // 调用第一个函数
console.log(func1(10, 5)); // 调用第二个函数
// 动态添加JavaScript函数到表
table.set(2, (a, b) => a * b);
// wasm可以调用这个JavaScript函数
instance.exports.call_table_function(2, 10, 5); // 50
</pre>
</div>
</div>
<h2>性能优化</h2>
<div class="interaction-demo">
<h3>减少交互开销</h3>
<div class="code-block">
<pre>
// ❌ 频繁调用,性能差
for (let i = 0; i < 1000000; i++) {
instance.exports.process_single(data[i]);
}
// ✅ 批量处理,性能好
const dataArray = new Float32Array(1000000);
// ... 填充数据
const ptr = instance.exports.alloc(1000000 * 4);
const wasmArray = new Float32Array(memory.buffer, ptr, 1000000);
wasmArray.set(dataArray);
instance.exports.process_batch(ptr, 1000000);
// ❌ 频繁字符串传递
for (let i = 0; i < 1000; i++) {
const str = `Item ${i}`;
const ptr = allocateString(str);
instance.exports.process_string(ptr);
deallocateString(ptr);
}
// ✅ 复用内存
const maxLen = 100;
const ptr = instance.exports.alloc(maxLen);
const buffer = new Uint8Array(memory.buffer, ptr, maxLen);
const encoder = new TextEncoder();
for (let i = 0; i < 1000; i++) {
const str = `Item ${i}`;
const bytes = encoder.encode(str);
buffer.set(bytes);
instance.exports.process_string(ptr, bytes.length);
}
instance.exports.dealloc(ptr, maxLen);
</pre>
</div>
</div>
<div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
<strong>东巴文提示:</strong>JavaScript与WebAssembly的交互需要理解内存布局、函数调用约定。减少跨边界调用、批量处理数据、复用内存,能显著提升性能。
</div>
</div>
</body>
</html>
完成本章学习后,请尝试回答以下问题:
选择题: WebAssembly的主要优势是什么?
填空题: Emscripten是将____代码编译为WebAssembly的工具链。
简答题: WebAssembly适合哪些应用场景?为什么?
实践题: 使用Emscripten编译一个简单的C函数(如计算斐波那契数列),并在JavaScript中调用。
应用题: 分析一个使用WebAssembly的实际项目(如Figma、Google Earth),总结其WebAssembly应用方式。