LilScript 号称比 terser 还能压 15%,但工程落地并不划算
看完 LilScript 的演示页,第一反应是:这不就是把 Closure Compiler Advanced Mode 的思路重新实现了一遍,再把类型系统塞进去,帮助压缩器做更准确的推断?
作者提供的 Vector 例子很直观:类被展开成标量,循环改写成 while,中间变量也全部消掉了。可问题是,这套做法在 Closure Compiler 里十年前就能做到,前提是给足类型注解、不使用动态属性访问,也不把对象当作 map 到处传递。
强类型约束能否换取更高的压缩率?
LilScript 的区别,是把这些限制直接写进语言层:你必须声明 float x、int[] values,否则无法通过编译。换句话说,它用语言层面的强约束,换取编译器对代码的完全掌控。
压缩率 5-15% 究竟从哪里来?
文档的描述相对诚实:在 gzip/brotli 之后还能继续省下这部分体积,主要依靠两件事。
第一,是把“对象字面量、类、闭包”这些人类写起来舒服、压缩器却很难处理的结构,强行压平成数组和标量。第二,是根据变量名在最终压缩流中的“熵贡献”进行重命名,而不是简单地把名字缩成单字母。
基于熵贡献的重命名方案有效吗?
后一个思路挺有意思:同一个短 token 重复出现得越多,压缩率就越高。因此,编译器会统计整个程序中最常出现的标识符模式,再反向计算出一套命名方案。切换 cost_model,还可以分别针对 gzip、brotli、raw 生成不同的命名表。
思路本身是通的,但收益会边际递减。比如在 200 KB 的 bundle 上再节省 10 KB,经过 gzip 后可能只差 300 字节,CDN 传输层面的 RTT 根本感知不到。
工程落地是否面临生态兼容性挑战?
真正的问题不在压缩器,而在生态
- Source map 怎么生成? 代码结构已经被重写得面目全非,想要映射回原始行号,可能只能依赖启发式近似。
- 动态属性、Proxy、eval、
import()、框架运行时注入的字符串键——只要出现一个,整条优化链就可能中断,退回保守模式。 - 第三方 npm 包不可能全部用 LilScript 编写,那么边界处如何处理?文档只说“works with pretty much any js/ts library”,没有给出互操作细节。
- README 中出现 Modified MIT license,商用前必须先经过法务审查,对很多团队来说,这本身就可能是否决项。
我用 marked(那个号称最快的 markdown 解析器)跑了下官方 demo
源码 42 KB → esbuild + terser 18.3 KB(gzip 6.1 KB)→ LilScript 17.5 KB(gzip 5.8 KB)。
体积确实小了 5%,但构建时间从 1.2s 增加到了 9.4s,同时出现 23 处 “property access may be external” 警告,全部指向库对外暴露的 API 字段。
作者提到的 “tryhard property mangling”,在真实库里基本无法发挥作用:公共 API 的属性名不能改,框架 hook 名不能改,DOM 字段更不能改。
利用 LLM 生成代码是否过于激进?
LLM oneshot 生成 LilScript 代码?
这个宣传语有些激进。现有模型即使生成不带类型的现代 JS,也容易出现运行时幻觉;指望它一次性写出既满足 LilScript 严格类型系统、又保持语义等价的代码,成功概率低得可怜。
它或许可以辅助“把现有 TS 迁移到 LilScript”,但后续人工兜底的成本依然很高。
结论
技术路线没有明显问题:需要压平的结构就压平,需要按熵重命名的部分就按熵重命名。但工程落地带来的边际收益停留在 5-15% 这个区间,很难抵过迁移成本、构建时长、调试困难和许可证风险。
除非你正在做 embedded JS runtime,或者在对体积极其敏感的 WebAssembly 落地页上工作,否则可以先观望半年,看看是否真的有大厂在生产环境中跑起来,再考虑采用。
全部回复 (3)
想当场把话说完?进全球 AI 聊天室,登录就能开口。
直接用 @unrestricted 标记 lib 就能死码消除,而且如果能给足类型注解、不使用动态属性访问,也不把对象当作 map 到处传递,这操作就更省事了!
直接用 swc 配手写 extern 效果就一样,没必要为了 15% 去学新语法,毕竟就像 LilScript 文档里说的,“把‘对象字面量、类、闭包’这些人类写起来舒服、压缩器却很难处理的结构,强行压平成数组和标量” 这种做法在 Closure Compiler 里十年前就能做到,前提是给足类型注解、不使用动态属性访问,也不把对象当作 map 到处传递。
赶紧去 GitHub 蹲个 Star,压掉 15% 的话这项目简直是宝藏,不然后面更难上手了,毕竟现在体积确实小了 5%,但构建时间从 1.2s 增加到了 9.4s,同时出现 23 处 “property access may be external” 警告,全部指向库对外暴露的 API 字段。