#binary-format #ast #javascript #reference #es6 #increase #encoding

nightly binjs_es6

Binary AST 引用实现的 ES6 组件

1 个不稳定版本

使用旧 Rust 2015

0.2.1 2018 年 11 月 22 日

#4 in #es6

MIT 许可证

365KB
7K SLoC

Travis Status

关于 JavaScript Binary AST 的介绍

随着网站变得越来越复杂,JavaScript 源代码的数量也在不断增加。虽然依赖大型 JavaScript 代码库不会阻止网站工作,但它会导致网站启动缓慢——往往非常 慢,难以接受。这是由于两个瓶颈:解析和编译 JavaScript 字节码。不幸的是,浏览器在这两项操作上的效率已经接近极限。

我们(Mozilla、Bloomberg、Facebook、CloudFlare)目前正在开发一种针对 JavaScript 的特定领域编码,称为“BinAST”(即“JavaScript Binary AST”)。JavaScript Binary AST 的设计目的是打破这个瓶颈。当前的高级原型已经显示出 JS 在所有最常见的框架中解析速度提高了 30%-50%(见链接),只需更改格式,我们相信我们可以进一步提高这个改进。这种编码可以作为 Web 开发工具链的一部分来构建,或者由代理或 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 源代码解析得更快,这得益于无需回溯的语法,不需要多次 intern 的字符串等。

二进制AST格式设计得非常巧妙,使得虚拟机可以在接收到文件的前几个字节后立即开始解析文件(流式解析),并在之后很快开始编译为字节码(流式字节码编译)。

此外,对JavaScript源代码的解析指定了特定的编码,这意味着在解析之前(或者在最佳情况下,在解析的同时)需要对这些编码进行转码,这会减慢解析速度。由于BinAST是一种二进制格式,因此不需要任何形式的转码。

最后,大多数现代JavaScript虚拟机支持一种懒解析的形式,这种解析方式在几乎不进行内存分配的情况下执行更快的解析。BinAST格式设计得允许解析器通过单个操作跳过(函数),从而在需要时使懒解析更高效。

规范

  • 语义规范在此处指定:链接
  • 二进制格式规范在此处指定:链接

lib.rs:

ES6 AST的强类型实现。

依赖项

~12MB
~361K SLoC