1 个不稳定版本
使用旧的 Rust 2015
0.1.1 | 2018年11月22日 |
---|
#162 在 #binary-format
被 2 crate 使用
22KB
555 行
关于 JavaScript 二进制 AST
随着网站变得越来越复杂,JavaScript 源代码的数量也在不断增加。虽然依赖于庞大的 JavaScript 代码库不会阻止网站工作,但会导致网站启动缓慢 - 常常是 不可接受地慢。这是由于两个瓶颈:解析和编译 JavaScript 字节码。不幸的是,浏览器在这两个操作上都已经达到了效率的顶峰。
我们(Mozilla、Bloomberg、Facebook、CloudFlare)目前正在开发一种针对 JavaScript 的特定领域编码,称为“BinAST”(代表“JavaScript Binary AST”)。JavaScript 二进制 AST 的设计目的是打破瓶颈。当前的先进原型已经显示,只需改变格式,就可以在所有最常用的框架上实现 JS 解析改进30%-50%,我们相信我们可以进一步增加这种改进。这种编码可以构建为 webdev 工具链的一部分,或者通过代理或 CDN 注入,从而无需更改原始网站即可自动提高最终用户的性能。
这种编码目前正在进行 JavaScript TC39 标准化流程 [3]。它可以与现有的压缩技术(gzip、brotli 等)一起使用
测试它
- 安装依赖项(您需要
npm
、rustup
)
npm install
rustup install nightly
rustup default nightly
- 拉取代码。
git clone https://github.com/binast/binjs-ref
- 压缩/解压缩。
cargo run --bin binjs_encode -- --help
cargo run --bin binjs_decode -- --help
注意 JS 解析器可能会在非常大的 JS 源文件上崩溃。如果是这样,您需要设置环境变量 NODE_MAX_OLD_SPACE_SIZE=xxxx
。这将指示基于 Node 的解析器分配更多内存。默认值是 2048(Mb)。这相当于向 Node 进程传递 --max_old_space_size
。
- 转储树结构。
cargo run --bin binjs_dump -- --help
注意 binjs_dump
仅支持 multipart
格式。
与 JavaScript 源代码的兼容性
保留
- 良好结构的程序的语义;
- 变量和函数名称。
不保留
- 语法错误的实际语义;
- 源代码位置;
- 格式(包括空白和分号);
- 注释(包括源映射)。
预期好处
二进制 AST 格式旨在比 JS 源更快地解析,这得益于不需要回溯的语法、不需要多次进行字符串化的字符串等。
二进制AST格式设计得如此,以至于虚拟机可以在接收到文件的前几个字节后立即开始解析文件(流式解析),随后可以很快地开始将文件编译成字节码(流式字节码编译)。
此外,对JS源代码的解析指定了特定的编码,这意味着在解析之前(或者在最好情况下,在解析过程中)需要将许多编码进行转码,这会减慢解析速度。由于BinAST是一种二进制格式,它不需要任何形式的转码。
最后,大多数现代JavaScript虚拟机支持一种懒解析形式,这种解析方式在不进行大多数内存分配的情况下进行更快的解析。BinAST格式设计得可以在需要的情况下通过让解析器在一次操作中跳过(函数)来使懒解析更加高效。
规范
依赖项
~1-1.7MB
~37K SLoC