1 个不稳定版本

使用旧的 Rust 2015

0.1.1 2018年11月22日

#162#binary-format


2 crate 使用

MIT 许可证

22KB
555

Travis Status

关于 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 等)一起使用

测试它

  1. 安装依赖项(您需要 npmrustup
npm install
rustup install nightly
rustup default nightly
  1. 拉取代码。
git clone https://github.com/binast/binjs-ref
  1. 压缩/解压缩。
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

  1. 转储树结构。
cargo run --bin binjs_dump -- --help

注意 binjs_dump 仅支持 multipart 格式。

与 JavaScript 源代码的兼容性

保留

  • 良好结构的程序的语义;
  • 变量和函数名称。

不保留

  • 语法错误的实际语义;
  • 源代码位置;
  • 格式(包括空白和分号);
  • 注释(包括源映射)。

预期好处

二进制 AST 格式旨在比 JS 源更快地解析,这得益于不需要回溯的语法、不需要多次进行字符串化的字符串等。

二进制AST格式设计得如此,以至于虚拟机可以在接收到文件的前几个字节后立即开始解析文件(流式解析),随后可以很快地开始将文件编译成字节码(流式字节码编译)。

此外,对JS源代码的解析指定了特定的编码,这意味着在解析之前(或者在最好情况下,在解析过程中)需要将许多编码进行转码,这会减慢解析速度。由于BinAST是一种二进制格式,它不需要任何形式的转码。

最后,大多数现代JavaScript虚拟机支持一种懒解析形式,这种解析方式在不进行大多数内存分配的情况下进行更快的解析。BinAST格式设计得可以在需要的情况下通过让解析器在一次操作中跳过(函数)来使懒解析更加高效。

规范

依赖项

~1-1.7MB
~37K SLoC