表演
⚠️ 正在开发中:Vize正在积极开发中,尚未准备好投入生产使用。基准数据来自开发版本,可能会有所变化。
Vize通过利用Rust的零成本抽象和原生多线程,相比标准基于JavaScript的Vue编译器实现了显著的性能提升。速度不是可有可无的——它是开发者经验的前提条件。
基准环境
以下历史号码是用本地工作站记录的。对于可重现的CI托管 适合发布说明和文档更新的数字,请使用 铁匠基准快照由工具基准工作流程生成。
| 机器 | MacBook Pro(M2 Max,12核,96GB内存) |
| OS | macOS 15.3.2 (Darwin 24.3.0) |
| Node.js | v24.14.0 |
| 快 | v8.0.0 (Rolldown) |
| Vue | v3.6.0-beta.10 |
基准测试:15,000 SFC 文件
正在编译15,000个Vue SFC文件(总共36.9 MB):
| @vue/编译器-sfc | 维泽 | 加速 | |
|---|---|---|---|
| 单线 | 9.35秒 | 3.47秒 | 2.7x |
| 多线索 | 4.08秒 | 353毫秒 | 11.6x |
| 编译器-sfc ST 与 Vize MT | 9.35秒 | 353毫秒 | 26.0x |
单线程的改进来自于 Rust 的零成本抽象(无 GC、无 JIT 预热、缓存友好的内存布局)。多线程的改进来自Rayon那剥夺工作的线程池,其几乎线性地随CPU核心数扩展。
原生批处理缩放行为
| 档案 | Vize批次(1线) | Vize批次(12个线) | 并联加速 |
|---|---|---|---|
| 100 | 25毫秒 | 3毫秒 | 8.5x |
| 1000 | 243毫秒 | 26毫秒 | 9.4x |
| 5,000 | 1.25秒 | 128毫秒 | 9.7x |
| 15,000 | 3.75秒 | 373毫秒 | 10.1x |
这些原生批号包含文件读取。小批量生产主要受固定开销主导;大批量的并行加速稳定在这台12核机器上约为10倍。
为什么是Rust?
零成本抽象
Rust 的所有权模式消除了垃圾回收暂停。编译器通过arena分配(vize_carton)处理AST节点,避免了每节点堆分配。这意味着:
无GC暂停— 在基于V8的编译器中,垃圾回收可能导致不可预测的延迟尖峰。Vize没有GC的开销。
无JIT预热— V8的JIT编译器需要时间来优化热路径。Vize从第一条指令开始就全速运行。
可预测的性能— Rust的提前编译意味着性能在不同运行间保持一致,不依赖于V8的优化启发式。
原生多线程
Vize 使用 Rayon 进行数据并行编译。每个SFC文件都是独立编译的,使得工作负载异常并行。Rayon的“抢工调度器”确保核心利用率最佳:
// Simplified: parallel compilation of all .vue files
files.par_iter().map(|file| {
let arena = Bump::new();
let ast = parse(file, &arena);
let analyzed = analyze(ast, &arena);
compile(analyzed, &arena)
}).collect()
工作窃取方法意味着,如果一个文件明显大于其他文件,空闲线程会从忙线程队列中窃取工作,保持近乎完美的负载均衡。
高效内存布局
Rust 的结构布局和枚举判别式都很紧凑。vize_relief 中的 AST 表示对缓存友好,减少了内存带宽瓶颈:
枚举判别式— 锈色枚举的大小为符合判别项的最小类型。拥有20个变体的
NodeKind使用单个字节,而非堆分配字符串。结构体打包— Rust 自动重新排序结构字段以实现最佳对齐,最小化填充字节。
无对象头— 与携带原型链、属性映射和隐藏类指针的JavaScript对象不同,Rust结构体纯数据,零开销。
无运行时间开销
与运行在 V8 上的基于 JavaScript 的编译器不同,Vize 直接编译为原生代码。没有JIT预热,没有垃圾回收器,也没有事件循环争用。编译器二进制是一个单一的静态链接可执行文件,能够以全速启动并运行。
性能架构选择
竞技场分配
vize_carton为使用 bumpalo 的 AST 节点提供一个缓冲分配器。这意味着:
分配为O(1)— 只需向前推一个指针即可。没有自由列表遍历,没有碎片管理。
分配为O(1)— 编译完成后一次性放弃整个竞技场。没有每个节点的分配开销。
内存局部性极佳— 节点连续地填充内存,最大化树遍历时的L1/L2缓存命中率。
这是相较于V8代际垃圾回收器的根本优势,后者需要定期追踪可达对象并压缩内存。
流媒体代币管理器
vize_armature的分词器将输入处理为字节流,避免了构建中间令牌数组的需求。解析器懒惰地消耗代币——每个代币按需生成并立即被消耗。这减少了峰值内存使用并改善了缓存行为。
弦乐实习
常见字符串(指令名、属性名、HTML标签名)通过compact_str和完美哈希表(phf)进行内隔。这意味着:
字符串比较是指针比较(O(1)),而非逐字符比较(O(n))
重复字符串共享单一分配
已知字符串的哈希查找通过编译时计算
增量合辑
Vite插件(@vizejs/vite-plugin)使用文件级缓存。开发过程中只有修改过的文件会被重新编译,从而最大限度地减少HMR延迟。缓存键是文件内容的哈希值,确保未更改的文件永远不会被重新编译。
基准测试:Linter — patina 与 eslint-plugin-vue 的比较
线条化15,000 个 Vue SFC 文件:
| eslint-plugin-vue (ST) | 维泽包浆(ST) | 加速 | eslint-plugin-vue (MT) | Vize包锈(MT) | 加速 | eslint ST vs Vize MT | |
|---|---|---|---|---|---|---|---|
| 时间 | 45.08秒 | 4.02秒 | 11.2x | 16.38秒 | 784毫秒 | 20.9x | 57.5x |
跑vp run --workspace-root bench:lint来繁殖。
类型感知绒毛配置文件
类型感知的附加处理在成本趋于聚集的阶段被有意描绘:SFC 解析, Croquis 分析、虚拟 TypeScript 生成、模板查询收集和 Corsa 探针。当 启用了多个模板支持的类型感知规则,Patina 收集模板表达式和 模板 Promise 查询在 Corsa 探测阶段前的一次 AST 走动中完成。查询集合也共享 OXC表达式解析用于unsafe模板和浮动承诺检查,因此一个模板表达式 当两个规则都启用时,不支付重复解析成本。
跑vize lint --profile --preset opinionated src去本地项目看看这些排。该
Profile Report还包括严格的审计部分,检查工作时间的累积覆盖情况
工作时间、慢阈值点击,以及在列出热文件和内部文件前捕获的内部时段
行动。热文件行显示每阶段的共享和吞吐量,操作行显示主导
跨度或最大/平均峰值。
基准测试:Formatter — 字形与更漂亮
格式化15,000 个 Vue SFC 文件:
| Prettier (CLI) | 维泽字形(ST) | 加速 | 维泽字形(MT) | Prettier CLI vs Vize MT | |
|---|---|---|---|---|---|
| 时间 | 101.20秒 | 2.97秒 | 34.1x | 835毫秒 | 121.2x |
跑vp run --workspace-root bench:fmt来繁殖。
基准测试:类型检查器 — 正史与vue-tsc的对比
类型检查500 生成的 Vue SFC 文件,采用当前 Corsa 支持的诊断路径:
| vue-tsc (ST) | 维泽正典(ST) | 加速 | vue-tsc (MT) | Vize正典(MT) | 加速 | vue-tsc ST vs Vize MT | |
|---|---|---|---|---|---|---|---|
| 时间 | 4.38秒 | 511毫秒 | 8.6x | 4.41秒 | 493毫秒 | 8.9x | 8.9x |
| 评分 | 114 文件/秒 | 979个文件/秒 | 113 个文件/秒 | 1.0k 文件/秒 |
注:Vize正能仍处于早期开发阶段,Corsa支持的诊断路径仍在追赶Vue-TSC的保真度。这些测量反映了当前以CLI为先的本地实现,采用项目会话备份,随着诊断覆盖和奇偶校验的提升,这些指标将发生变化。
在cargo build --release -p vize后运行node bench/check.ts 500以复现这个快速基准测试。
类型检查员配置文件
500-SFC 配置文件灯具将大部分墙时存储在 Corsa CLI 命令中,而导入重写快速路径则消除了之前未使用 Vue 指定符文件的 OXC 解析成本:
| 公制 | 在 | 现状 |
|---|---|---|
canon.import.rewrite.vue |
26.77毫秒 | 2.45毫秒 |
| 生成的最大虚拟TS | 15,401B | 14,414B |
| 总轮廓壁时间 | 1.88秒 | 668毫秒 |
| 科萨诊断阶段 | 1.67秒 | 482毫秒 |
| Corsa CLI parse | 无 | 10.41毫秒 |
Rust侧的 virtual project 阶段——每文件的 SFC 解析,Croquis 分析,
虚拟 TS 生成和导入重写——在 rayon 的话题中被扇动
VirtualProject::register_paths里的泳池。每个.vue文件都是独立的
一旦工作区选项解析完成,一个批次就能并行化
干净利落。在1000 SFC的灯具上,相位从~71毫秒降至~25毫秒之前
甚至还提到了科萨。
重诊断的 e2e 灯具
当灯具存在时,bench/check.ts还会测量tests/_fixtures/_git/npmx.dev应用。这会捕捉真实应用夹具上的诊断映射路径:
| 固定装置 | 来源SFC文件 | 虚拟文件 | 诊断 | 维兹正史 |
|---|---|---|---|---|
| npmx.dev 应用 | 134 | 226 | 1,053 | 1.94秒 |
该灯具当前配置文件保持CLI诊断解析在~7毫秒。大部分时间现在都集中在 Corsa CLI 命令本身。将框架自动导入存根提升到一个环境文件中,也使生成的最大虚拟TS文件从约275KB减少到144KB。
基准测试:Vite 插件 — @vizejs/vite-plugin 与 @vitejs/plugin-vue 的比较
Vite 构建,包含1,000个Vue SFC导入(全部导入于单一条目):
| @vitejs/plugin-vue | @vizejs/vite-plugin | 加速 | |
|---|---|---|---|
| 建造时间 | 957毫秒 | 479毫秒 | 2.0x |
注:
@vizejs/vite-plugin仅替代了Vue的SFC编译步骤——性能差异完全来自该步骤。依赖关系解析、模图构建、捆绑(Rolldown)及其他所有 Vite 内部结构与@vitejs/plugin-vue完全相同。关于纯编译性能,请参见上文的编译器基准测试。@vizejs/vite-plugin热切地利用原生多线程编译预编译.vue文件,这也使 HMR 更快。
跑vp run --workspace-root bench:vite来繁殖。