如何优化服务和加载JavaScript文件?

Ada*_*nch 7 javascript networking cdn download assetic

我希望有更多全球规模网络应用程序经验的人可以澄清一些问题,假设和可能的误解.

让我们来看一个假想的网站(大量的客户端/动态组件),它在全球拥有数十万用户,并且来自一个地方(比如中欧).

  1. 如果应用程序依赖于流行的JavaScript库,那么从Google CDN中获取它并将其编译成一个简化的JS文件(以及所有特定于应用程序的JavaScript)或者将其与Google CDN分开加载会更好吗?
  2. Assetic VS headjs:加载一个JS文件或并行加载所有脚本(按依赖顺序执行)更有意义吗?

我的假设(请纠正我):

将所有特定于应用程序的/本地JS代码编译到一个文件中,使用像Google这样的流行库等CDN,但是通过headjs并行加载所有这些代码似乎是最佳的,但我不确定.服务器端将第三方JS和特定于应用程序的JS编译到一个文件中似乎几乎打败了使用CDN的目的,因为无论如何库都可能缓存在用户的某个位置.

除了缓存之外,从Google的CDN下载第三方库可能比托管应用程序的中央服务器更快.

如果发布一个流行的JS库的新版本,性能大大提升,则使用该应用程序进行测试,然后实现:

  • 如果所有JS都编译成一个文件,那么即使应用程序代码没有改变,每个用户也必须重新下载该文件.
  • 如果从CDN加载第三方脚本,则用户仅从CDN(或从某处的缓存)下载新版本.

在描述的情况下,是否存在以下任何合理的担忧?

  • 某些用户(或浏览器)一次只能与一个主机名建立一定数量的连接,因此从第三方CDN检索某些脚本将导致整体加载时间更快.
  • 某些用户可能在受限制的环境中使用该应用程序,因此该应用程序的域可能是白名单但不是CDN的域.(如果这可能是现实问题,是否可以尝试从CDN加载并在发生故障时从中央服务器加载?)

can*_*lin 8

将所有特定于应用程序的/本地JS代码编译到一个文件中

由于我们的一些关键目标是减少HTTP请求的数量最小化请求开销,因此这是一种非常广泛采用的最佳实践.

我们可能认为不这样做的主要情况是频繁缓存失效的可能性很大,即当我们对代码进行更改时.这里总会有权衡:提供单个文件很可能会增加缓存失效率,而提供许多单独的文件可能会导致缓存为空的用户启动较慢.

出于这个原因,偶尔插入一些特定于页面的JavaScript并不像有些人所说的那样邪恶.一般来说,将JS连接和缩小为一个文件是一个很好的第一步.

使用像谷歌这样的CDN用于流行的图书馆等.

如果我们讨论的是我们正在使用的代码是相当不可变的库,即不太可能受到高速缓存失效的影响,我可能会更倾向于通过将它们包装到单片本地JS文件中来保存HTTP请求.对于大量基于例如特定jQuery版本的大型代码库来说尤其如此.在这样的情况下,库版本几乎肯定会涉及对客户端应用程序代码的重大更改,否定将它们分开的优势.

尽管如此,混合请求域是一个重要的胜利,因为我们不希望被每个域名上限的最大连接过度限制.当然,子域名也可以用于此,但Google的域名具有无cookie的优势,并且可能已经在客户端的DNS缓存中.

但通过headjs并行加载所有这些似乎是最佳的

虽然新兴的JavaScript"加载器"主机有优势,但我们应该记住,使用它们会对页面启动产生负面影响,因为浏览器需要在加载器请求其余资产之前获取加载器.换句话说,对于具有空缓存的用户,在开始任何实际加载之前需要到服务器的完整往返.同样,"编译"步骤可以解决 - 请参阅require.js以获得出色的混合实现.

确保脚本不阻止UI绘制的最佳方法仍然是将它们放在HTML的末尾.如果您宁愿将它们放在别处,那么asyncdefer属性现在为您提供了灵活性.所有现代浏览器并行请求资产,因此除非您需要支持特定版本的旧客户端,否则这不应该是主要考虑因素.该Browserscope网络表是对这种事情有很大的参考.IE8可以预见为主要攻击者,在加载脚本之前仍会阻止图像和iFrame请求.即使回到3.6, Firefox也完全并行化了iFrames.

某些用户可能在受限制的环境中使用该应用程序,因此该应用程序的域可能是白名单但不是CDN的域.(如果这可能是现实问题,是否可以尝试从CDN加载并在发生故障时从中央服务器加载?)

如果客户端计算机可以访问远程主机,则总是会导致严重的性能损失,因为我们必须等待它才能加载我们的保留副本之前无法连接.我更倾向于在本地托管这些资产.