浏览器parsing每个页面加载的JavaScript?

浏览器(IE和Firefox)每次页面刷新时都parsing链接的JavaScript文件吗?

他们可以caching这些文件,所以我猜测他们不会每次下载它们,但是由于每个页面本质上是分开的,所以我希望他们能够拆除旧的代码并重新parsing它们。

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

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


Chrome:V8引擎

V8有一个编译caching。 这存储了编译的JavaScript,使用源代码的散列,最多5个垃圾回收。 这意味着两个相同的源代码将在内存中共享一个caching条目,而不pipe它们是如何包含的。 重新加载页面时,此caching不会被清除。

资源


更新 – 19/03/2015

Chrome团队已经发布了关于JavaScriptstream媒体和caching新技术的细节 。

  1. 脚本stream

脚本stream式传输优化了JavaScript文件的parsing。 […]

从版本41开始,一旦下载开始,Chrome会在单独的线程上parsingasynchronous和延期的脚本。 这意味着parsing可以在下载完成后几毫秒内完成,并导致页面加载速度提高10%。

  1. 代码caching

通常情况下,V8引擎会在每次访问时编译页面的JavaScript,将其转化为处理器能够理解的指令。 一旦用户离开页面,编译后的代码将被丢弃,因为编译代码在编译时高度依赖于机器的状态和上下文。

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


歌剧:卡拉坎引擎

实际上,这意味着无论何时编译脚本程序,其源代码与最近编译的某个其他程序的源代码都相同,我们将重新使用编译器的前一个输出并完全跳过编译步骤。 这种caching在典型的浏览场景中非常有效,因为每个页面通常会加载相同的,有时甚至是非常大的脚本库,这种情况下,从同一个站点加载页面,比如来自新闻服务的不同新闻报道。

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

资源


Firefox:SpiderMonkey引擎

SpiderMonkey使用Nanojit作为它的本地后端,一个JIT编译器。 编译机器代码的过程可以在这里看到。 简而言之,它似乎在加载脚本时重新编译脚本。 但是,如果我们仔细看看 Nanojit的内部,我们看到用于跟踪编译的更高级的监视器可以在编译过程中经过三个阶段,为Nanojit提供了一个好处:

跟踪监视器的初始状态正在监视。 这意味着spidermonkey正在解释字节码。 每当spidermonkey解释一个反跳字节码,监视器就会logging跳转目标程序计数器(PC)值被跳转到的次数。 这个数字被称为PC的命中数。 如果特定PC的命中次数达到阈值,则认为目标是热的。

当显示器决定一个目标电脑是热的时候,它会查看一个碎片的散列表,看看是否有一个片段保存该目标电脑的本地代码。 如果发现这样的片段,则转换到执行模式。 否则,转换到录制模式。

这意味着对于代码的hot片段,本地代码被caching。 意思是不需要重新编译。 不清楚的是,这些散列的本地部分保留在页面刷新之间。 但我会认为他们是。 如果任何人都可以find支持这个优秀的证据。

编辑 :有人指出,Mozilla开发人员鲍里斯Zbarsky说,壁虎不caching编译的脚本 。 从这个SO回答 。


Safari:JavaScriptCore / SquirelFish引擎

我认为这个实施的最佳答案已经由其他人给出了 。

我们目前不caching字节码(或本地代码)。 它是一个
我们已经考虑过,但是目前代码生成是一个
JS执行时间的微小部分(<2%),所以我们不追求
此刻此刻。

这是由Safari的首席开发者Maciej Stachowiak编写的。 所以我认为我们可以认为这是事实。

我无法find任何其他信息,但您可以在这里阅读有关最新SquirrelFish Extreme引擎的速度改进的更多信息,或者如果您觉得冒险,可以在这里浏览源代码。


IE:查克拉引擎

目前没有关于IE9的JavaScript引擎(Chakra)在这个领域的信息。 如果有人知道任何东西,请评论。

这是相当不正式的,但对于IE较老的引擎实现,Eric Lippert( JScript的MS开发人员 )在博客中回复说:

JScript Classic就像一个编译语言,在任何JScript Classic程序运行之前,我们完全语法检查代码,生成一个完整的分析树,并生成一个字节码。 然后我们通过字节码解释器运行字节码。 从这个意义上说,JScript和Java一样都是“编译”的。 不同的是,JScript不允许你坚持或检查我们的专有字节码 。 此外,字节码比JVM字节码高得多 – JScript Classic字节码语言不过是parsing树的线性化,而JVM字节码显然是要在低级堆栈机器上运行。

这表明字节码不会以任何方式持续存在,因此字节码不会被caching。

歌剧做它,如在其他答案中提到的。 ( 来源 )

Firefox(SpiderMonkey引擎)不caching字节码。 ( 来源 )

WebKit(Safari,Konqueror)不caching字节码。 ( 来源 )

我不知道IE [6/7/8]或V8(Chrome),我认为IE可能会做某种caching,而V8可能不会。 IE是封闭源代码,所以我不确定,但是在V8中,直接编译为机器代码会caching“编译”代码可能没有意义。

据我所知,只有Operacachingparsing的JavaScript。 请参阅此处的 “caching编译的程序”一节。

Google Dart通过“Snapshots”明确解决这个问题是没有任何价值的 – 目标是通过加载预编译的代码版本加快初始化和加载时间。

InfoQ有一个很好的文章@ http://www.infoq.com/articles/google-dart

我认为正确的答案是“不总是”。 据我所知,浏览器和服务器在确定caching的内容方面发挥了作用。 如果你真的需要每次重新加载文件,那么我认为你应该能够从Apache内部进行configuration(例如)。 当然,我想用户的浏览器可以configuration为忽略该设置,但这可能不太可能。

所以我会想象,在大多数实际情况下,JavaScript文件本身被caching,但每次页面加载时都会被dynamic地重新解释。

浏览器肯定会使用caching,但是,浏览器每次刷新页面时都会parsingJavaScript。 因为无论浏览器何时加载页面,都会创build2棵树1.内容树和2.render树。

这个渲染树由关于dom元素的可视布局的信息组成。 所以每当一个页面加载时,javascript被parsing,而javascript的任何dynamic变化都会像定位dom元素,show / hide元素,add / remove元素会导致浏览器重新生成渲染树。 但像FF和chrome这样的现代化的broswers处理方式略有不同,它们具有渐进式渲染的概念,所以每当上述js发生dynamic变化时,只会导致这些元素再次渲染和重绘。