Ale*_*ian 27 javascript browser dom
今天我在想这个,我意识到我这里没有清晰的图片.
以下是我认为是真实的一些陈述(如果我错了,请纠正我):
我很好奇我打电话后幕后发生的事情document.getElementById('foo').调用是否由解释器委托给浏览器本机代码,或者浏览器是否具有所有主机对象的JS实现?你知道他们对此做了什么优化吗?
我阅读了浏览器内部的这个概述,但它没有提到任何关于这个的内容.我有空的时候会浏览Chrome和FF源码,但我想先问一下这里.:)
您的所有要点都是正确的,除了:
现代JS解释器使用JIT来提高代码性能并将其转换为字节码
应该是"......并将其翻译为本机代码".SpiderMonkey(Firefox中的JS引擎)在当前的JS速度军备竞赛之前很长一段时间用作字节码解释器.
在Mozilla的JS-to-DOM桥上:
宿主对象通常用C++实现,尽管正在进行实验以在JS中实现DOM.因此,当网页调用时document.getElementById('foo'),通过其ID检索元素的实际工作是在C++方法中完成的,正如hsivonen所指出的那样.
调用底层C++实现的具体方式取决于API,也随着时间的推移而改变(请注意,我没有参与开发,因此可能错误的一些细节,这是jst的一篇博文,他实际参与了创建大部分代码):
getElementById,执行必要的参数检查/转换并将调用直接路由到C++方法(nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn))特别是对于最后三点的细节,我很模糊,所以把它带上一粒盐.
最新的改进被列为bug 622298的依赖项,但我没有密切关注它们.
JS调用DOM方法,例如getElementById使JS引擎调用实现DOM的C++代码.例如,在Firefox中,呼叫最终会进入nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn).
正如您所看到的,Firefox维护一个哈希表,在这种情况下,它将ids映射到C++中的元素作为优化,因此它不会遍历整个DOM树来查找id.
DOM在所有主要的浏览器实现中都被实现为独立于语言的库,这意味着它与Javascript引擎位于不同的库中.例如,在IE中,JS引擎是在jscript.dll实现DOM时实现的mshtml.dll.Safari有Nitro(JS)和WebCore(DOM).Chrome有V8(JS)和WebCore(DOM),Firefox有SpiderMonkey/TraceMonkey(JS)和Gecko(DOM).
这意味着,只要你的JS必须访问DOM,它就必须到达DOM库 - 由于必须进行的所有编组操作,这本身就很慢.已经使用的类比是通过收费桥连接的2块土地,无论何时触摸DOM,您都必须越过桥并交叉 - 支付性能损失.