5

不是让 V8 即时编译 JavaScript然后执行它,难道不能只预先编译 JavaScript 然后将机器代码嵌入页面而不是将 JavaScript 嵌入页面吗?

4

2 回答 2

8

在网络上发送机器码有两个主要问题:

  1. 便携性。没有服务器能够为所有可能的系统架构(现在和未来)提供适当的机器代码。例如,V8 已经支持 10 种不同的 CPU 架构。
  2. 安全。没有客户可以在不知道是否可以信任的情况下在他们的机器上运行随机机器代码。

要解决 (1) 问题,您通常需要交叉编译机器代码,这比从高级语言编译下来更加困难和昂贵。要解决 (2),您需要验证您收到的机器代码,这比编译高级语言更困难且成本更高。

机器代码也往往比高级代码大得多,因此也存在带宽问题。

现在,JavaScript 可能不是一个特别好的高级语言选择。但这是我们作为网络语言所坚持的。

于 2015-04-22T20:32:56.430 回答
5

按照我的理解,V8 JavaScript 引擎无论如何都会编译成机器码,那为什么不事先做呢?

根据W3C HTML5 Scripting specification ,浏览器支持具有特殊type属性的机器代码(就像 Chrome 对 Dart 语言所做的那样)没有基于标准的原因:

下面列出了用户代理必须识别的 MIME 类型字符串,以及它们所引用的语言:

"application/ecmascript"
"application/javascript"
...

用户代理可能支持其他语言的其他 MIME 类型...

目前,还没有浏览器实现这样的功能。

我怀疑这种方法的主要缺点是每个芯片架构都需要专门为其编译的脚本的机器代码版本。这意味着为了支持三种架构,一个页面需要包含三次编译脚本。(并且应该第四次包含它,作为纯 JavaScript,作为您未包含的架构或不能/不支持编译代码的浏览器的后备。)这可能会显着膨胀包含大部分无用数据的页面。加载时间的增加似乎会大大抵消或完全超过您节省的编译时间。

像字节码这样的独立于体系结构的折衷解决方案似乎很差:您仍然需要包含两次脚本(一次用于字节码,一次通常用于不支持它的脚本)并且您需要在字节码将其转换为机器码。

多重包含与回退问题正是其他脚本语言没有进入 Web 环境的原因:它们需要协调的跨供应商支持才能有用。谷歌正在尝试 Dart,但他们看到的成功程度还有待观察。

请注意,Chrome 确实会缓存脚本的编译版本,因此脚本只需要编译一次,然后编译的代码会被缓存以供用户重新访问该页面时重复使用。

于 2015-04-22T19:40:47.513 回答