9

编辑澄清:

性能方面(尽管我知道这仍然是一个疯狂的术语),哪个更好 - 通过 RequireJS 加载本地版本或 jQuery 的 CDN 版本?

作为记录,RequireJS 在线文档包含一些似乎不鼓励使用 CDN 的段落,尽管我不确定 100% 是什么意思:

不要在构建中混合 CDN 加载和 shim 配置。示例场景:您从 CDN 加载 jQuery,但使用 shim 配置加载依赖于 jQuery 的 Backbone 的库存版本。进行构建时,请确保在构建文件中内联 jQuery,并且不要从 CDN 加载它。否则,Backbone 将内联在构建的文件中,并在加载 CDN 的 jQuery 加载之前执行。这是因为 shim 配置只是延迟加载文件,直到加载依赖项,但不执行任何自动包装定义。构建后,依赖项已经内联,shim 配置不能延迟执行未定义()的代码,直到以后。定义()' d 模块在构建后确实与 CDN 加载的代码一起工作,因为它们正确地将其源代码包装在定义工厂函数中,该函数在加载依赖项之前不会执行。所以教训:shim config 是非模块化代码、遗留代码的权宜之计。定义()的模块更好。

从理论上讲,使用 CDN jQuery 文件会导致多出 1 个 HTTP 请求(不能使用 r.js 与其他 JS 文件合并),但潜在的好处是您的访问者可能已经从他们的其他站点缓存了 CDN 版本去过。

但是,如果我从谷歌搜索的信息中得到它,您仍然需要为 r.js 提供本地 jQuery 副本,因为生成的缩小 JS 文件仍需要包含 jQuery 模块的副本以确保依赖关系的一致性。这将导致通过本地和 CDN 加载 jQuery。(希望我得到了正确的部分?)

那么,哪种方式更好呢?

4

3 回答 3

6

简短回答:避免额外的 HTTP 请求和 DNS 查找

您最好使用自己的副本并让 RequireJS 合并文件。换句话说,我会说避免额外的http请求和DNS查找更有价值。

虽然用户可能已经从另一个站点的缓存中拥有该文件,但他们很可能不会。即使他们最近访问过另一个站点,缓存大小通常也足够小,以至于在一两次正常浏览会话期间,用户可以轻松填满他们的缓存,在这种情况下,旧文件将被丢弃。

我认为您最多只会谈论 1% 的流量已经在缓存中包含 CDN 文件,因此只有 1% 的用户从中受益。但是,通过结合这些资源并避免额外的 http 请求,您将受益于 99% 的用户。所以相反,如果不合并,你会伤害 99% 的用户。只是另一种看待这个的方式。

另一个考虑因素是移动用户......移动用户有可怕的延迟,因此额外的 http 请求和 dns 查找的 RTT 具有更大的成本。

于 2012-08-27T12:44:25.287 回答
6

您的 requirejs 文档引用专门关于使用具有 jQuery 垫片配置的脚本。如果所有脚本都是 AMD 模块,则可以从第三方 CDN 动态加载基础依赖项。

缓存命中率并不像您想象的那样高(我相信雅虎对缓存与非缓存状态进行了研究),这意味着您现在必须依赖另一个域进行加载。

好处可能取决于应用程序,对其进行分析将导致最佳答案。例如,如果它是一个有很多图片的网站,那么 jquery 的策略就不那么重要了,因为图片加载可能是更明显的性能问题。

我会首先将 jQuery 优化到构建的文件中,并对所有内容使用 AMD 模块,所以如果我想委托给 CDN,我可以。但是,如果使用 requirejs 和 shim 配置,则需要在构建文件中内联基本依赖项,因为 shimmed 库不调用 define() - 他们不等待依赖项加载,他们希望它们立即可用。

于 2012-08-29T17:06:08.563 回答
4

人们已经缓存了文件不仅是事实。用户代理只能同时从同一个域加载几个文件。因此,从 CDN 加载 JS 文件可确保文件将同时加载。

这对已经拥有文件缓存版本的用户有利。所以对于流行的文件(例如 jQuery javascript),我总是从 CDN 加载它。

如果 CDN 由于某种原因而关闭,您始终可以向本地版本添加回退。

笔记

尽管 RFC 规定用户代理应该同时执行最多 2 个请求,但现在大多数用户代理都忽略了这个规范。另请参阅关于 SO 的旧(2009 年)问题。请注意,用户代理当前执行更多请求并不会让我感到惊讶。

于 2012-08-27T12:23:11.540 回答