因为 WebAssembly 的出现,很多的编程语言被带到了 Web,进入了更多前端er的视野,Rust 就为其中之一。本文将使用 Dodrio 来 渲染十万个待办事项并随机消灭一半( 灭霸本霸),抱着学习使用的心态顺带测试一下它的速度。
Dodrio 是一个用 Rust 和 WebAssembly 编写的虚拟 DOM 库。它利用了 Wasm 的线性内存和 Rust 的低层次控制 api ,围绕指针碰撞(bump allocation)的方式来设计虚拟 DOM 渲染机制。初步的基准测试结果表明它比现有的虚拟 DOM 库性能都高。
link:http://www.alloyteam.com/2020/01/dodrio-rust-wasm-fast-vdom/
开始前白话简介一下相关名词,建议跳过
WebAssembly
是一种编译目标,将 C/C++/Rust/Go 等语言的编译为二进制格式后可供 Javascript 使用。因其跳过了 JavaScript 运作的 Parser 阶段,能带来性能上的提升。
WebAssembly 是被设计成 JavaScript 的完善与补充,而不是一个替代品。
虚拟 DOM (Virtual DOM)
将 DOM 状态生成一份虚拟的树结构,在需要更新的时候,使用差异(diff)算法来尽可能减少调用 DOM 的相关方法(因为性能不好),通常缓存没有变更的组件来避免重新渲染。 Virtual DOM 在重复渲染大量数据的时候你能明显感觉到提升,但并不意味着任何场景用了就会带来性能的飞跃,这一点在后文有做简单的测试。
手动斜眼( ﹁ ﹁ ) ,WebAssembly 和 Virtual DOM 都能提升性能,那用 Rust 的 vdom 库来渲染咱的待办列表岂不是快(♂)上加快(♂)。
React vs 原生
在使用 Rust 编写之前,为了打消咱的好奇,决定先测试一下咱们常用的 React(没错,它也是使用了 Virtual DOM 并还带 了一把)和原生的差距。
测试目的
原生 JS 和 采用了 vdom 的框架渲染大量数据的时间上的差距。
测试方式
测试方式为渲染十万个待办列表,然后统计点击第一次随机消灭到完成渲染所需要的时间。
Round 1
使用 create-react-app 创建一个模板项目,修改 App.js:
function App() {
const size = 100 * 100 * 10;
const [todoList, setTodoList] = useState(
Array(size)
.fill(1)
.map((_, index) => `待办事项${index}`)
);
function onDelete() {
setTodoList(todoList.filter(() => Math.random() > 0.5));