我希望有人与全球规模的网络应用程序更多的经验可以澄清一些问题,假设和可能的误解我。
让我们以一个假想的网站,其中有全球成千上万的用户和资源正在从一个位置服务(客户端/动态分量重量)(比方说中欧)。
- 如果应用程序依赖于流行的JavaScript库,倒不如把它从谷歌CDN并把它编译成一个单一的缩小的JS文件(连同所有应用程序特定的JavaScript),或从谷歌CDN单独加载它?
- Assetic VS headjs :它更有意义加载一个单个的JS文件或负载并联的所有脚本(依赖关系的顺序执行)?
我的假设 (请指正):
编译所有专用/本地JS代码到一个文件中,使用像谷歌的CDN的流行库等,但在通过并行加载headjs所有这些似乎是最佳的,但我不知道。 第三方JS和特定应用的JS到一个文件中的服务器端编译似乎几乎打败使用CDN,因为库可能沿着用户的线缓存的地方反正目的。
除了缓存,它可能更快地从谷歌的CDN下载一个第三方库比反正托管应用程序的中央服务器。
如果一个流行的JS库的新版本发布时有一个大的性能提升,与应用程序进行测试,然后执行:
- 如果所有的JS编译成一个文件,那么每个用户将不得不重新下载,即使在应用程序代码并没有改变这个文件。
- 如果第三方脚本从加载的CDN然后用户只下载来自CDN的新版本(或从缓存中某处)。
像一个描述的以下任一合法担忧的情况呢?
- 有些用户(或浏览器)只能拥有一定数量的连接到一个主机名一下子让从第三方CDN将导致总体更快的加载时间检索某些脚本。
- 有些用户可能使用的应用程序在受限制的环境,所以应用的领域可能是白名单,但不是的CDN的域。 (如果这是可能的,这是现实的关注,是在所有可能尝试从CDN和负载从加载失败中央服务器?)
编译所有专用/本地JS代码到一个文件
由于我们的一些关键目标是减少HTTP请求的数量和最小化要求的开销 ,这是一个很广泛采用的最佳实践。
在这里我们可以考虑不这样做的主要案例是在有频繁缓存失效,即高的机会,当我们修改我们的代码的情况。 总是会有权衡这里:服务于单个文件很可能会增加缓存失效的速度,同时为许多独立的文件可能会导致用户较慢的开始空缓存。
出于这个原因,内联特定页面的JavaScript偶尔有点不一样邪恶有些人说。 虽然在一般,串联和涅槃你的JS到一个文件是一个伟大的第一步。
使用像谷歌的CDN的流行库等
如果我们谈论的是,我们正在使用的代码是相当不可变的,即不会受到缓存失效图书馆,我可能会赞成通过包装他们进入你的单片本地JS文件保存HTTP请求的稍微定。 这将是很大程度上依赖于一个大的代码库,例如jQuery的特别版本尤其如此。 在这样的情况下,碰撞库版本几乎可以肯定你的客户端应用程序代码显著变化太大涉及,否定保持它们分开的优势。
尽管如此, 混合请求域是一个重要的胜利 ,因为我们不希望被每个域帽的最大连接数过多节流。 当然,一个子域可以起到一样好这一点,但谷歌的域名有被无Cookie的优势,并且可能已经在客户端的DNS缓存。
但通过headjs并行加载所有这些似乎是最佳
虽然有许多的JavaScript的“装载机”新兴的主机的优势,我们应该记住,使用起来确实页面开始产生负面影响,因为浏览器需要去获取我们的装载机前装载机可以要求我们的资产的剩余部分。 换句话说,对于一个空的缓存之前,任何真正的负载可以开始一个完整的往返需要服务器的用户。 同样,“编译”步能出手相救-看到require.js为一个伟大的混合实现。
确保你的脚本不阻止UI画的最好办法仍然是把它们放在你的HTML结束。 如果你宁愿把它们放在别的地方,在async
或defer
属性现在为您提供这种灵活性。 所有现代浏览器请求并行的资产,所以,除非你需要支持旧版客户端的特定口味这不应该是一个重要的考虑因素。 该Browserscope网络表是对这种事情有很大的参考。 IE8是可以预见的主要罪犯,直到脚本加载仍然阻止图像和iframe的请求。 即使回到3.6火狐充分parallelising一切,但iFrame中。
有些用户可能使用的应用程序在受限制的环境,所以应用的领域可能是白名单,但不是的CDN的域。 (如果这是可能的,这是现实的关注,是在所有可能尝试从CDN和负载从加载失败中央服务器?)
工作了,如果客户机可以访问远程主机总是会招致严重的性能损失,因为我们不得不等待它无法连接之前,我们可以载入我们保留副本。 我会更倾向于本地托管这些资产。
编译所有专用/本地JS代码到一个文件中,使用像谷歌的CDN的流行库等,但在通过并行加载headjs所有这些似乎是最佳...
我会说,这是基本上是正确的。 不要多个外部库合并成一个文件,因为,因为它似乎你知道,这将否定的用户的浏览器多数情况下,具有高速缓存的(个人)资源了。
为了你自己的应用程序特定的JS代码,你可能要做出一个要考虑的是如何往往将对此进行更新。 例如,如果存在的功能,将不经常改变的核心,但可能会经常改变一些更小的组件,它可能是有意义的只编译(由我假定你的意思再压缩/压缩)的核心成一个文件,同时继续服务更小的部分零碎。
你的决定也应该考虑你的JS资产的规模。 如果,这是不可能的,但可能的,你是服务的一个非常大的量的JavaScript,串联这一切到一个文件中可能会起到反作用,因为一些客户端(如移动设备),对他们将缓存什么很严格的限制。 在这种情况下,你会过得更好的服务小资产屈指可数。
这些只是随机的花絮让你做到心中有数。 我想提出的主要观点是,你的本能反应(以上报价)可能是正确的做法。