当前位置:  开发笔记 > 编程语言 > 正文

浏览器是否在每个页面加载时解析javascript?

如何解决《浏览器是否在每个页面加载时解析javascript?》经验,为你挑选了2个好方法。

浏览器(IE和Firefox)每次页面刷新时都会解析链接的javascript文件吗?

他们可以缓存文件,因此我猜他们不会每次都尝试下载它们,但由于每个页面基本上是分开的,我希望它们可以拆除任何旧代码并重新解析它.

这是低效的,虽然完全可以理解,但我想知道现代浏览器是否足够聪明以避免站点内的解析步骤.我在想一个网站使用javascript库的情况,比如ExtJS或jQuery等.



1> Jivings..:

这些是我能够挖掘的细节.首先值得注意的是,尽管JavaScript通常被认为是在VM上进行解释和运行,但现代解释器并不是这种情况,现代解释器倾向于将源代码直接编译为机器代码(IE除外).


Chrome:V8引擎

V8有一个编译缓存.这使用源的哈希存储编译的JavaScript,最多可存储5个垃圾收集.这意味着两个相同的源代码将共享内存中的缓存条目,无论它们是如何包含的.重新加载页面时不会清除此缓存.

资源


更新 - 19/03/2015

Chrome团队发布了有关JavaScript流媒体和缓存新技术的详细信息.

    脚本流

脚本流优化了JavaScript文件的解析.[...]

从版本41开始,Chrome会在下载开始后立即在单独的线程上解析异步和延迟脚本.这意味着解析可以在下载完成后的几毫秒内完成,并使页面加载速度提高10%.

    代码缓存

通常情况下,V8引擎会在每次访问时编译页面的JavaScript,并将其转换为处理器可以理解的指令.一旦用户导航离开页面,该编译的代码就被丢弃,因为编译代码在编译时高度依赖于机器的状态和上下文.

Chrome 42引入了一种存储已编译代码的本地副本的高级技术,因此当用户返回页面时,可以跳过下载,解析和编译步骤.在所有页面加载中,这使Chrome可以避免大约40%的编译时间,并在移动设备上节省宝贵的电池.


歌剧:Carakan Engine

实际上,这意味着无论何时编写脚本程序,其源代码与最近编译的其他程序的源代码相同,我们都会重用编译器的先前输出并完全跳过编译步骤.这种缓存在典型的浏览场景中非常有效,其中一个页面从同一站点加载页面,例如来自新闻服务的不同新闻文章,因为每个页面通常加载相同的,有时非常大的脚本库.

因此,JavaScript在页面重新加载时被缓存,对同一脚本的两个请求不会导致重新编译.

资源


Firefox:SpiderMonkey引擎

SpiderMonkey使用NanojitJIT编译器作为其本机后端.编译机器代码的过程可以在这里看到.简而言之,它似乎在加载时重新编译脚本.但是,如果我们仔细研究内部结构,Nanojit我们会看到jstracer用于跟踪编译的更高级别监视器可以在编译期间转换为三个阶段,从而为以下方面提供了一个好处Nanojit:

跟踪监视器的初始状态是监视.这意味着spidermonkey正在解释字节码.每次spidermonkey解释向后跳转字节码时,监视器都会记录跳转目标程序计数器(PC)值跳转到的次数.此编号称为PC的命中计数.如果特定PC的命中计数达到阈值,则认为目标是热的.

当监视器确定目标PC很热时,它会查看片段的哈希表,以查看是否存在包含该目标PC的本机代码的片段.如果找到这样的片段,它将转换为执行模式.否则它将转换为录制模式.

这意味着对于hot代码片段,本机代码被缓存.意义不需要重新编译.在页面刷新之间保留这些散列的原生部分并不清楚.但我会认为他们是.如果有人能为此找到支持证据那么优秀.

编辑:它已经指出,Mozilla开发鲍里斯Zbarsky曾表示,壁虎不缓存编译脚本.取自这个SO答案.


Safari:JavaScriptCore/SquirelFish Engine

我认为这个实施的最佳答案已经由其他人提供.

我们目前不缓存字节码(或本机代码).这是
我们考虑过的一个选项,但是,目前,代码生成是
JS执行时间的一个微不足道的部分(<2%),所以我们目前不追求
这一点.

这是由Safari的首席开发人员Maciej Stachowiak撰写的.所以我认为我们可以认为这是真的.

我无法找到任何其他信息,但你可以阅读更多有关最新的速度提高SquirrelFish Extreme发动机在这里,或浏览源代码,在这里,如果你喜欢冒险的感觉.


IE:Chakra引擎

目前还没有关于IE9的JavaScript引擎(Chakra)的信息.如果有人知道,请发表评论.

这是相当非正式的,但对于IE的旧的引擎实现,埃里克利珀(JScript中的MS开发商)在博客中回应称这里是:

JScript Classic就像编译语言一样,在任何JScript Classic程序运行之前,我们完全语法检查代码,生成完整的解析树,并生成字节码.然后我们通过字节码解释器运行字节码.从这个意义上说,JScript就像Java一样被"编译".不同之处在于JScript不允许您持久化或检查我们的专有字节码.此外,字节码比JVM字节码高得多 - JScript Classic字节码语言只不过是解析树的线性化,而JVM字节码显然是为了在低级别的堆栈机器上运行.

这表明字节码不会以任何方式持久存在,因此字节码不会被缓存.


+1,优秀的写作.但是,关于Firefox,请参阅[此StackOverflow问题](http://stackoverflow.com/questions/5957720/if-javascript-interpreter-does-jit-compilation-does-it-cache-results-of-it-fo )Mozilla开发人员Boris Zbarsky解释说Gecko目前不这样做.
@Jivings以上述为来源.(我是喀拉坎队的一员.)

2> cha0site..:

正如其他答案所述,Opera就是这样做的.(来源)

火狐(SpiderMonkey的引擎),并没有缓存的字节码.(来源)

WebKit的(Safari浏览器,Konqueror中)确实缓存字节码.(来源)

我不确定IE [6/7/8]或V8(Chrome),我认为IE可能会进行某种缓存,而V8可能不会.IE是封闭源,所以我不确定,但在V8中,缓存"编译"代码可能没有意义,因为它们直接编译为机器代码.


字节已被IE用于...永远.这在IE8中并不新鲜.这仅仅是因为给定一个解释器,解释器的性能比解析时慢得多,这完全是无关紧要的.IE9有一个全新的(从头开始)JS引擎,因此两者之间没有任何内容.
推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有