用WebAssembly做矩阵运算后更新DOM卡顿怎么办?

一翌耀 阅读 104

我在用WebAssembly优化矩阵乘法运算时遇到问题,用Emscripten编译的C代码计算正确,但每次计算完用JavaScript更新表格时页面会卡顿半秒。我尝试过把计算部分放进Web Worker,但调用wasm实例时又报错:


worker.postMessage({ type: 'calculate', data: matrix });
// 报错:Cannot transfer a WebAssembly.Memory object

现在用主线程计算虽然能更新界面,但大数据量时表格渲染还是卡。CSS用了table-layout: fixed,但感觉没帮助:


.matrix-table {
  border-collapse: collapse;
  table-layout: fixed;
  width: 100%;
}
.matrix-cell {
  width: 40px;
  text-align: right;
}

哪里出了问题?是Web Worker用法不对,还是DOM更新方式太低效?

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
西门柯欣
问题出在两处:WebAssembly.Memory不能直接传给Worker,DOM批量更新太频繁。解决方案:

先把wasm内存转成ArrayBuffer传递,worker里再转回TypedArray:
// 主线程
const memory = wasmInstance.exports.memory;
worker.postMessage({ type: 'init', buffer: memory.buffer }, [memory.buffer]);

// worker线程
let sharedMemory;
onmessage = function(e) {
if (e.data.type === 'init') {
sharedMemory = new Uint8Array(e.data.buffer);
}
};


然后用DocumentFragment一次性更新DOM,别逐个单元格改:
const fragment = document.createDocumentFragment();
matrix.forEach(row => {
const tr = document.createElement('tr');
row.forEach(val => {
const td = document.createElement('td');
td.textContent = val;
tr.appendChild(td);
});
fragment.appendChild(tr);
});
tableBody.replaceChildren(fragment); // 搞定
点赞
2026-02-19 15:18