9

问题一

为什么我需要在网页中异步加载我的 JavaScript 文件?我可以在服务器端看到它的基本原理,但是如果我知道我需要在客户端加载的所有文件,为什么我不应该将所有源文件连接到 1 个文件中并在页面加载时加载呢?第一个初始页面加载是否如此重要,以至于将来的操作可能会由于检索每个 JS 文件的延迟而减慢?

问题 2

假设问题1的答案是我需要单独加载JS文件:

AMD 异步加载每个 JS 文件,CommonJS 同步加载。服务器端加载需要 CJS(如果我没记错的话,这就是 Node.js 的工作方式)。AMD 似乎更适合客户。因此,在客户端使用 CJS 的唯一原因是与服务器共享代码。

有没有办法让 AMD 和 CJS 玩得很好,以便客户端 JS 文件可以异步加载但仍然具有 CJS 语法?

(require.js 到底是做什么的?我一生都无法在他们网站上的字里行间阅读。)

4

3 回答 3

3

仅连接文件的部分问题不在于下载所花费的时间,而是在每个页面上编译所花费的时间。

如果你有一个 20,000 行的文件,而你只需要其中的 600 行就可以让所有东西都启动并运行(假设所有东西都是模块化和异步的,使用任何模式来管理资源),那么你'如果您为核心程序提供服务并根据需要进行扩展(或在延迟的计时器上,为彼此密切相关的大量功能提供服务),那么您可能会节省半秒或更长时间。

下载所花费的总时间更长。
使用的 HTTP 连接总数更高。
但是使页面对用户可见所需的时间较短。
向页面添加基本功能所需的时间较短。
然后额外的功能可以在加载和初始化之后,或者根据用户的要求,在这两种情况下,只要你输入的代码专注于做那个,就可以输入额外的功能事情,并且不要求六个其他依赖项,请求和添加功能之间的时间将是最短的。

RequireJS 基本上使用了一个承诺系统。

它允许您预先声明依赖项,并在处理完所有依赖项之后提交要实现的代码(作为回调)。
如果这些依赖项有任何依赖项,那么在加载它们的依赖项之前它们不会被初始化。
如果你只想加载它并且顺序并不重要,那么你不需要给它依赖。

总的道理是,如果你有一个所有文件都很小的系统,页面上 JS 的总重量非常小,你只需要几百行就可以在页面上做你想做的一切...... ...另外,您知道所有依赖项在哪里,您在服务器上有一个系统来确保它们的顺序正确,等等(另外,您有很好的文档,或者您是唯一的一个谁接触了这段代码,而你每天都生活在其中)......那么做你正在做的事情就没有任何问题。

如果编译时间超过了您发出的 HTTP 请求的数量,您可能根本看不到任何差异。但是对于具有数万(或数十万)行长的整体应用程序,其中任何一个页面上只需要该功能的一小部分,就可以大大节省页面加载到页面加载时间之间的感知时间。应用程序已“准备好”进行用户的基本交互。

于 2012-10-02T20:24:11.940 回答
3

如果您想为每个页面加载整个 javascript 源代码,请确保将其编译到一个文件中。如果您根据用户执行的操作或加载的页面加载不同的代码,请使用 AMD 加载的模块。另一种选择是列出一堆脚本标签,当然一次只能加载一个并且可能需要一段时间。

AMD 不是一个特定的库,它实际上是加载您提到的大多数加载器使用的 javascript 模块的标准。这意味着它们都使用相似的语法来定义和加载模块。他们正在考虑让 AMD 成为 ECMA 脚本规范的一部分。它的用处在于您还可以定义依赖项,因此如果您的代码需要运行 jQuery,您可以将其列为依赖项,并将其加载到您的模块命名空间中。

define( [ 'jquery' ], function ( $ ) {
    // use jquery in here without clouding up the global namespace

    return {}; // return your module for use in a different module or whatever
};

在此示例中,在下载 jquery 模块之前,不会运行已定义模块中的代码。然后它将 jquery 模块作为参数直接注入到您新定义的模块中$

您现在可以将代码整齐地组织到包含模块的文件中。您的任何模块都不会混淆全局命名空间。您的所有依赖项都将确保在您的模块运行之前已加载(没有加载依赖代码段的竞争条件错误)。

另一个优点是您可以将加载程序设置为对同一模块使用不同的路径,因此您可以将jquery模块的路径定义为“https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/ jquery.min.js' 在您的代码中的一个位置,即使它几乎可以在每个模块中使用。jquery现在,当我需要将我的 jquery 版本更新到 1.8.3 时,我可以简单地在我的代码中的一个位置更改路径,它将为每个用作依赖项的模块使用此路径。当您使用模块存根或调试某些模块的版本时,这对于在测试时轻松切换也很有用。

现在,小型项目不一定需要这样做。但是,您的项目越大,这种类型的加载就越有意义。

于 2012-10-02T21:25:58.647 回答
3

您不需要“需要”异步或通过某些自定义加载器加载 javascript 文件。以下是异步加载或自定义加载可能带来好处的一些原因:

  • 当通常不需要 javascript 文件并且您可能希望按需而不是一直加载它时
  • 当初始页面显示不需要 javascript 文件并且您希望最大化页面的首次显示速度时
  • 当您想控制加载 javascript 文件的确切时间时
  • 当您根据某些条件决定是否加载 javascript 文件时(例如,如果从 CDN 加载失败,您可能会从备份位置加载)
  • 当您希望脚本加载与其他事情并行进行而不是一个接一个地序列化时

如果您不需要任何这些好处或程序加载提供的其他好处,那么您可以只使用普通<script>标签并让它们同步加载。

于 2012-10-02T20:09:14.317 回答