it-swarm.cn

为什么在通过网络发送JavaScript之前未将其编译为字节码?

您经常会看到JavaScript实际上是通过Web传输的,其中包含了所有不需要的东西注释,特别是那些包含许可证的注释,缩进'\ t''\ n'),等等。如果有足够的时间,它最终可能会浪费掉数TB的全球数据! JavaScript字节码会导致另一个更大的问题,还是没人想到这个?

155
Vivek Yadav

为什么在通过网络发送JavaScript之前未将其编译为字节码?

背景:1990年代末,我曾在ECMAScript技术委员会任职,并且是Microsoft JScript引擎的实现者之一。

首先,我要面对“为什么不这么做”时总是说些什么?问题:不需要语言设计师给出充分的理由,说明他们为什么没有在某人喜欢的功能上花费数亿其他人的钱。相反,要求使用此功能的人员给出充分的理由说明为什么这是花费时间,精力和金钱的最佳方式。您已经提出了一个没有附加任何数字的参数,即就带宽而言,字节码可以节省成本。我鼓励您计算一些实际数字,并将其与创建另一种语言的成本进行比较;这些费用是巨大的。请记住,在您的分析中,“实施”是最小的成本之一。在您的分析中还包括谁节省钱与谁支出钱,您会发现花钱的人不是省钱的人。激励措施很重要。

就是说,这是更合理的“为什么不呢?”之一提出质疑,因为它是我们出于考虑而拒绝的功能。

我们在Microsoft内部和TC级别都考虑过这种方案;由于JScript已被实现为编译为设计良好的,原则性的字节码语言,因此对于我们而言,将其作为标准提出来是很简单的,因此我们考虑这样做。

由于多种原因,我们决定不这样做:

  • 天哪,很难标准化JavaScript。每个人和他们的狗都会对字节码语言的理想特性有何看法,这将是很多年的经验。没有人真的想去那里。
  • 这是一个昂贵的解决方案,没有相关的昂贵问题。没有理由认为字节码语言在大小或速度上都会更有效率。 JavaScript已经很好地压缩了并且可以高度压缩。
  • 它将为浏览器提供者创造大量工作,而这些浏览器提供者已经为制作高效,兼容的JS实现而感到烦恼。
  • 创建一个安全的JS实现以抵抗不良行为者的攻击已经足够困难了。我们应该将可攻击的表面积增加一倍吗?可能不是。
  • 标准是创新的障碍。如果我们发现对字节码语言的微小更改会在某些以前无法预见或不重要的用户场景中产生很大的不同,那么我们可以自由地进行更改。如果这是一个标准,我们将无法自由创造用户利益。

但是,该分析假定完全要执行该功能的原因是性能。有趣的是,客户在1990年代出于动机考虑使用此功能的要求主要与性能无关。

为什么不?对于JS而言,1990年代与今天截然不同。脚本很小。关于某天将有成千上万条线的框架的想法甚至还没有接近我们的视野。下载和解析JS仅占下载和解析HTML所花费时间的一小部分。

动机也没有扩展到其他语言,尽管Microsoft也很感兴趣,因为我们也使VBScript在浏览器中运行,该浏览器使用了非常相似的字节码语言。 (由同一团队开发,并使用相同的来源和全部方法进行编译。)

相反,在浏览器中激发字节码的主要客户场景是使代码更难以阅读,理解,反编译,反向工程和篡改。 对于任何有合理资源的攻击者来说,字节码语言几乎都不是要理解的任何其他工作,这是进行此工作的主要要点;我们不想造成错误的安全感。

基本上,这笔费用很多,收益却很少,所以它没有完成。在1998年至2015年之间,必须有所改变,以使WebAssembly具有合理的价格效益。这些因素是什么,我不知道。您必须向WebAssembly咨询专家。

381
Eric Lippert

查看资料

“查看源代码”最初只是在某种程度上仍被认为是网络的重要功能,但在某种程度上仍然如此。这是几代Web开发人员学习Web开发的方式,相关标准机构(ECMA TC39,W3C,WHATWG)仍然非常重视它。

缩小

ECMAScript文件通常在部署之前被“缩小”。这包括删除所有注释,所有空格以及将所有标识符重命名为尽可能短,以及一些更高级别的优化,例如删除无效代码。

压缩

自HTTP/1.0(1996年初)开始,HTTP中就开始支持压缩。 ECMAScript是文本,并且文本压缩非常好。实际上,ECMAScript是具有很多冗余的文本(很多;{}(),.functionvariffor,依此类推),压缩算法在冗余度上蒸蒸日上。因此,传输的数据量比您实际确定的要少得多。作为实验,请尝试使用网络上使用的一种典型压缩算法(例如gzip或deflate)压缩ECMAScript源文件,然后将其与同一文件的已编译字节码大小进行比较。

字节码格式

这就引出了下一个问题:ECMAscript没有标准化的字节码格式。实际上,某些实现甚至可能根本不使用字节码!例如,在最初的几年中,V8直接将ECMAScript编译为本地机器代码,而中间没有字节码。 Chakra,SquirrelFish Extreme和SpiderMonkey都使用字节码,但是它们使用不同的字节码。 dyn.js,TruffleJS,Nashorn和Rhine不使用ECMAScript特定的字节码,它们会编译为JVML字节码。同样,IronJS编译为CLI CIL字节码。

现在,您可能会说:为什么不define ECMAScript的标准化字节码格式?这个问题有两个方面:

  1. 字节码格式限制了执行引擎的设计。例如,看一下JVM:JVM比ECMAScript引擎彼此更相似。我个人认为,如果没有缺乏标准字节码格式的大量试验,就不可能实现2000年代末/ 2010年代初的“性能竞赛”。

  2. 不仅很难使所有ECMAScript引擎供应商都同意一种通用的标准化字节码格式,而且要考虑这一点:在浏览器中添加only ECMAScript的字节码格式是没有意义的。 如果,您使用通用的字节码格式,如果它也支持ActionScript,VBScript,Python,Ruby,Perl,Lua,PHP等,那就太好了。但是现在您遇到了与#1中相同的问题,除了成倍增加:不仅所有ECMAScript引擎供应商都需要就通用字节码格式达成一致,而且还必须获得PHP,Perl,Ruby,Python,Lua等。社区也同意!

快取

规范URI托管着广泛使用的知名库,可以在多个站点中引用它们。因此,它们只需要下载一次就可以在客户端缓存。

CDN

许多图书馆都使用CDN,因此实际上是从靠近用户的位置提供CDN的。

Wasm/asm.js

WebAssembly(Wasm) 是一种紧凑的二进制指令格式,目前已由W3C标准化,并且已经在Firefox,Chrome,Safari和Edge中提供。但是,它并不是ECMAScript的字节码格式,而是作为C,C++和Rust等语言的低级便携式机器代码和编译目标。

在Wasm之前,已经有目标相似的asm.js,但是它被设计为ECMAScript的语法和语义子集,因此您可以在不支持asm.js的引擎中未经修改地运行它,并且可以正常工作慢得多。

114
Jörg W Mittag

JavaScript是Netscape发明的。设计目标是通过嵌入式脚本语言使网页具有交互性。它最初并不是用于复杂的应用程序的,复杂的东西应该写成Java applet或插件,JavaScript被定位为简单的“胶水”代码,可以将HTML元素与= Java小程序和其他可编写脚本的插件。

JavaScript被设计为直接嵌入HTML中,例如<input type="button" onclick="alert('hello world')">。如今,人们不赞成在HTML中嵌入JavaScript,但是在那时,这是连接事件处理程序的标准方法。在这种情况下,JavaScript基本上必须基于文本。

还有一些用于在JavaScript中生成HTML的工具,例如:

<script>
  document.write("<input type=\"button\" onclick=\"alert('hello world')\">"
</script>

同样,这基本上需要JavaScript为文本格式才能有用。

此外,文本格式对临时开发人员来说很多更容易,因为您不需要开发环境即可将其编译为字节码。您只需键入文本并重新加载浏览器即可看到它运行。在引入JavaScript的时候,专用的HTML编辑器几乎不存在。人们在记事本中编写网页。没有诸如用于网页的构建管道之类的东西。

您提到的不利因素在当时并不是真正的考虑因素。由于它是为小型脚本而设计的,因此文本格式的开销是完全可以忽略的。

18
JacquesB

数据使用实际上可能不是问题。

要响应体内的假设(因为美妙的 Eric Lippert的响应 似乎已经很好地涵盖了实际问题):

无论您是在谈论数据上限还是带宽,我的Google-Fu都无法发掘任何表明Javascript实际上是“浪费了数TB的数据”的研究(无论如何)。

至于其余的问题,在很多情况下,问“这将导致什么问题?”的用处不大。而不是首先问“这将带来什么好处?”。

1
sp88