浏览器(IE和Firefox)每次刷新页面都会解析链接的javascript文件吗?
它们可以缓存文件,因此我猜想它们不会每次尝试下载文件,但由于每个页面本质上是分开的,我期望它们拆除任何旧代码并重新解析它。
这是低效的,虽然完全可以理解,但我想知道现代浏览器是否足够聪明,以避免在站点内进行解析步骤。我考虑的情况是站点使用了一个javascript库,比如ExtJS或jQuery等。
浏览器(IE和Firefox)每次刷新页面都会解析链接的javascript文件吗?
它们可以缓存文件,因此我猜想它们不会每次尝试下载文件,但由于每个页面本质上是分开的,我期望它们拆除任何旧代码并重新解析它。
这是低效的,虽然完全可以理解,但我想知道现代浏览器是否足够聪明,以避免在站点内进行解析步骤。我考虑的情况是站点使用了一个javascript库,比如ExtJS或jQuery等。
Chrome: V8引擎
V8有一个编译缓存。它使用源代码的哈希值来存储已编译的JavaScript,最多可存储5个垃圾回收。这意味着两个相同的源代码将共享内存中的缓存条目,无论它们是如何被包含的。当页面重新加载时,此缓存不会被清除。
更新 - 2015年3月19日
Chrome团队发布了有关他们的JavaScript流媒体和缓存新技术的详细信息。
脚本流媒体优化了JavaScript文件的解析。[...]
从版本41开始,Chrome会在下载开始后立即将异步和延迟脚本解析到单独的线程中。这意味着解析可以在下载完成后仅几毫秒内完成,并且导致页面加载速度提高了多达10%。
Opera : Carakan Engine
实际上,这意味着每当要编译一个脚本程序时,如果其源代码与最近编译的某个其他程序完全相同,我们将重用编译器的先前输出并完全跳过编译步骤。在典型的浏览场景中,这种缓存非常有效,因为用户经常从同一网站加载页面,例如从新闻服务加载不同的新闻文章,每个页面通常都会加载相同的(有时非常大的)脚本库。
因此,JavaScript 跨页面重新加载是被缓存的,对同一脚本的两个请求不会导致重新编译。
Firefox : SpiderMonkey引擎
SpiderMonkey使用JIT编译器Nanojit作为其本地后端。可以在此处看到编译机器代码的过程。简而言之,它似乎会在脚本加载时重新编译脚本。但是,如果我们更仔细地观察Nanojit的内部结构,我们会发现高级监视器jstracer在编译过程中可以通过三个阶段进行转换,从而使Nanojit受益:
跟踪监视器的初始状态是监视。这意味着spidermonkey正在解释字节码。每次spidermonkey解释一个向后跳转的字节码时,监视器都会记录跳转目标程序计数器(PC)值已经被跳转的次数。该数字称为PC的命中数。如果特定PC的命中计数达到阈值,则将目标视为热点。编辑: Mozilla 开发者 Boris Zbarsky 表示 Gecko 目前还没有缓存已编译的脚本。引自 这个 Stack Overflow 回答。
Safari: JavaScriptCore/SquirrelFish引擎
我认为对于这个实现来说,最好的答案已经由其他人给出。
我们目前不缓存字节码(或本地代码)。虽然我们考虑过这个选项,但是目前,代码生成只占JS执行时间的一个微不足道的部分(<2%),所以我们暂时不追求这个方向。
这是由Safari的首席开发人员Maciej Stachowiak编写的。所以我认为这是真实可信的。
我找不到其他信息,但你可以在这里阅读有关最新的SquirrelFish Extreme
引擎速度提升的更多信息,或者如果你感到冒险,在这里浏览源代码。
IE:Chakra引擎
目前没有关于IE9的JavaScript引擎(Chakra)在这个领域的任何信息。如果有人知道,请评论。
这是相当非官方的,但对于IE旧版引擎实现,Eric Lippert(MS JScript开发人员)在博客回复此处中指出:
这意味着字节码不以任何方式持久存在,因此字节码不会被缓存。JScript Classic的行为类似于编译语言,因为在运行任何JScript Classic程序之前,我们完全语法检查代码,生成完整的解析树,并生成字节码。然后我们通过字节码解释器运行字节码。从这个意义上说,JScript和Java一样“编译”。区别在于,JScript不允许您保留或检查我们的专有字节码。此外,字节码比JVM字节码高级得多 - JScript Classic字节码语言几乎只是解析树的线性化,而JVM字节码显然旨在在低级堆栈机上操作。
InfoQ在http://www.infoq.com/articles/google-dart上有一个很好的介绍。
我认为正确的答案应该是“并非总是如此”。据我所知,浏览器和服务器都在确定缓存内容方面发挥作用。如果您确实需要每次重新加载文件,则应该能够从Apache(例如)内部进行配置。当然,我想用户的浏览器可能会配置忽略该设置,但这可能不太可能。
因此,我想在大多数实际情况下,JavaScript 文件本身被缓存,但每次页面加载时都会动态重新解释。