15

因为我在工程师身边工作了这么多年,我知道如果我不提供上下文,我只会得到一百个“你想完成什么?”形式的答案。我将给出激发我的问题的背景。但不要混淆我所问问题的背景上下文,这与使对象代码在 padge 请求之间无法缓存的 JavaScript 语义特别相关。我不会给关于如何让我的 webapp 更快的建议打分。这与我的问题完全相切,这可能只有从事过 JavaScript 编译器或至少是动态语言编译器的人才能回答。

背景:

我正在尝试提高 Web 应用程序的性能。在它的众多资源中,它包含一个巨大的 JavaScript 文件,它有 40k 行和 130 万个预压缩字符。缩小后它仍然很大,并且在同步加载时它仍然增加了大约 100ms 到 window.onload 事件,即使源被缓存在客户端也是如此。(通过查看请求日志并观察它没有被请求,我已经最终排除了资源没有被缓存的可能性。)

在确认缓存后仍然很慢后,我开始研究主流浏览器中的JavaScript缓存,并了解到它们都没有缓存目标代码。


我的问题是基于这项研究的一些假设性断言的形式。如果这些断言是错误的,请反对。

  1. JavaScript 对象代码不会缓存在任何现代浏览器中。

    “对象代码”可以指任何东西,从表示简单线性化分析树的字节代码一直到本机机器代码

  2. Web 浏览器中的 JavaScript 对象代码很难缓存。

    换句话说,即使您在外部标记中包含缓存的 JS 源文件,在页面上包含该脚本也会产生线性成本,即使该脚本仅包含函数定义,因为所有该源都需要被编译成目标代码。

  3. JavaScript 对象代码很难缓存,因为必须评估 JS 源代码才能编译。

    语句有能力以难以静态分析的动态方式影响下游语句的编译。

    3a。(3) 是正确的,主要是因为 eval()。

  4. 评估会对 DOM 产生副作用。

  5. 因此,需要在每个页面请求上编译 JavaScript 源代码。

额外的问题:任何现代浏览器是否为缓存的 JS 源文件缓存解析树?如果不是,为什么不呢?

编辑:如果所有这些断言都是正确的,那么我会给任何可以解释为什么它们是正确的人的答案,例如,通过提供一个无法缓存为目标代码的 JS 代码示例,然后解释原因不是。

我很欣赏有关如何从这里开始以使我的应用程序更快的建议,我大多同意他们的看法。但我试图填补的知识空白与 JS 对象代码缓存有关。

4

1 回答 1

7

你是对的,它是动态编译和评估的。
你是对的,它必须是。

您的追索权不是试图使编译时间更小。
它需要从一开始就减少加载,做最少的工作以使用户体验可见,然后做最少的工作以模块化方式添加核心功能,然后是懒惰的(在计时器上或根据要求由最终用户)加载附加特性、功能和繁荣。

如果你的程序是 10,000 行程序代码,那么你就有问题了。
我希望这不是程序性的。

所以分手吧。这意味着较慢的第一页加载。但是在后续请求中,这可能意味着用户认为“正在运行”的响应时间要快得多,即使要达到 100% 的功能需要更长的时间。

这完全是关于用户对“速度”和“响应能力”的感知,而不是关于 100% 功能的最短线路。

单线程格式的 JavaScript 不能同时做到这一点做出响应。
所以先反应过来。

PS:添加一个引导程序智能引导。它应该能够辨别需要哪些功能。
RequireJS 用于加载依赖项。
不是为了弄清楚你的依赖关系是什么。

一个额外的好处——你可以在引导程序上设置一个短期缓存,它将指向版本化的模块。这有什么好处?好吧,如果您需要更新模块,在引导程序中更新版本是一个简单的过程。当引导程序的缓存过期时,它指向新模块,该模块可以有无限的生命周期(因为它有一个不同的名称——版本化或时间戳);

于 2012-09-19T15:51:10.240 回答