WebAssembly

JS在引擎中的过程

词法分析:分词生成token

一个个字幕扫描,与定义好的JavaScript关键字进行比较。token是不可分割的最小单元。

js 复制代码
    [
      { type: 'Const', value: 'const', start: 0, end: 5 },
      { type: 'Identifier', value: 'a', start: 6, end: 7 },
      { type: 'Assign', value: '=', start: 8, end: 9 },
      { type: 'Number', value: '1', start: 10, end: 11, raw: '1' },
      { type: 'Semicolon', value: ';', start: 11, end: 12 },
    ]

语法分析:通过Parser生成AST(规定结构的对象)

生成中间字节码

由解释器生成可运行的字节码。(为了在跨平台的基础上做到提升效率,保护代码安全)

热点代码编译成机器码

被即时编译器转换成机器码。只有热点代码会编译成机器码,为了平衡启动速度和执行效率。热点代码(例如多次调用的函数,多次循环体等),引擎通过性能计数器监控代码执行频率,当达到阈值时触发编译。

可以看到,代码中的热点代码会被进行编译成机器码,下一次执行就能直接执行机器码来提高效率。但是我们JS中是动态类型的语言,一个变量可以赋值给不同的类型。就行这次翻译的机器码限定类型为Object类型,下次执行到发现是Array类型,那么又要重新进行编译。

asm.js出现

asm.js是一个Javascript的严格子集,合理合法的asm.js代码一定是合理合法的JavaScript代码,但是反之就不成立。同WebAssembly一样,asm.js不是用来给各位用手一行一行撸 的代码,asm.js是一个编译目标

C / C++ 编译成 JS 有两个最大的困难。

  • C / C++ 是静态类型语言,而 JS 是动态类型语言。
  • C / C++ 是手动内存管理,而 JS 依靠垃圾回收机制。

asm.js 就是为了解决这两个问题而设计的:它的变量一律都是静态类型,并且取消垃圾回收机制。 除了这两点,它与 JavaScript 并无差异,也就是说,asm.js 是 JavaScript 的一个严格的子集,只能使用后者的一部分语法。

asm.js强制静态类型,举个例子。

js 复制代码
function asmJs() { 
'use asm'; 
let myInt = 0 | 0; 
let myDouble = +1.1; 
}

WebAssembly

如果你对 JS 比较了解,可能知道还有一种叫做 WebAssembly 的技术,也能将 C / C++ 转成 JS 引擎可以运行的代码。那么它与 asm.js 有何区别呢?

回答是,两者的功能基本一致,就是转出来的代码不一样:asm.js 是文本,WebAssembly 是二进制字节码,因此运行速度更快、体积更小。从长远来看,WebAssembly 的前景更光明。

优点:

  1. 🚀 性能接近原生 (Near-Native Performance)

这是 Wasm 最广为人知的优点。通过预编译的二进制格式和高效的 JIT 编译到原生机器码,Wasm 在执行 CPU 密集型任务时远超传统 JavaScript。

  • 应用场景:3D 游戏、视频/音频处理、科学计算、加密、物理模拟。
  1. 🌐 语言生态的极大扩展 (Language Ecosystem Expansion)

Wasm 允许开发者使用他们最擅长的语言来为 Web 编写高性能模块,而不仅仅局限于 JavaScript。

  • 支持的语言:C, C++, Rust 是"一等公民",Go, C#, Swift, Python, Java 等也通过不同工具链得到了支持。
  • 核心价值:这意味着可以将数十年积累下来的、经过实战检验的非 JS 库和应用移植到 Web 上。

缺点:

  1. 🌉 与 JavaScript 的交互开销 (JavaScript Interop Overhead)

这是目前 Wasm 最大的性能陷阱。频繁地在 JS 和 Wasm 之间来回调用函数或传递数据是非常昂贵的。

  • 问题根源:数据需要在线性内存和 JS 对象之间来回复制和转换。

  • 负面影响:如果使用不当(例如,用 Wasm 频繁操作 DOM),性能可能比纯 JS 实现还要差得多。

  1. 🕸️ 无法直接访问 Web API (No Direct Web API Access)

Wasm 被关在沙箱里,它不能像 JS 那样直接调用 document.getElementById()fetch()。所有这些操作都必须通过 JS 作为"中间人"来完成,这增加了复杂性和"胶水代码"的数量。

相关推荐
Z***u65910 小时前
前端性能测试实践
前端
xhxxx10 小时前
prototype 是遗产,proto 是族谱:一文吃透 JS 原型链
前端·javascript
倾墨10 小时前
Bytebot源码学习
前端
用户938169125536010 小时前
VUE3项目--集成Sass
前端
S***H28310 小时前
Vue语音识别案例
前端·vue.js·语音识别
啦啦91188611 小时前
【版本更新】Edge 浏览器 v142.0.3595.94 绿色增强版+官方安装包
前端·edge
蚂蚁集团数据体验技术11 小时前
一个可以补充 Mermaid 的可视化组件库 Infographic
前端·javascript·llm
LQW_home11 小时前
前端展示 接受springboot Flux数据demo
前端·css·css3
q***d17311 小时前
前端增强现实案例
前端·ar
IT_陈寒11 小时前
Vite 3.0 重磅升级:5个你必须掌握的优化技巧和实战应用
前端·人工智能·后端