将所有Javascript文件合并成一个文件后发送给客户端有什么好处?

8
例如,如果你有以下代码:
<body>
    <script src="someLibrary.js"></script>
    <script src="someLibrary2.js"></script>
    <script src="someLibrary3.js"></script>
    <script src="someLibrary4.js"></script>
    <script src="myApp"></script>
</body>

除了美观外,将所有这些内容通过任务运行(Grunt / Gulp)进行连接和压缩,并在发送给客户端之前进行处理,有什么好处?
<body>
    <script src="allTheJavascripts.js"></script>
</body>

1
客户端对服务器的请求减少了吗? - DontVoteMeDown
3个回答

20
  • 把多个JS文件合并成一个文件有以下好处:
    1. 浏览器可以比下载多个较小的文件更高效、更快地下载单个文件。通常,使用一个http连接下载该文件比使用许多http连接下载较小的文件更快。
    2. 浏览器对于同一域名会有同时建立连接的限制,如果达到了这个限制,一些连接就必须等待其他连接完成,这会导致下载延迟。下载较少的文件可以降低达到此限制的可能性。此限制适用于所有连接到一个域名的请求(包括JS文件下载、CSS文件下载、框架下载、ajax调用等)。
    3. 服务器的可扩展性可以提高,因为每个页面下载需要的http连接数更少。
    4. 在某些情况下,版本控制和版本升级与浏览器JS文件缓存之间的交互可能会更简单,因为只有一个较大的JS文件。当您的所有JS文件被串联在一起时,您可以为该组合JS文件分配一个单独的版本号(例如jQuery与其版本一样)。然后,对任何JS文件的更改都会导致主组合文件的版本号增加。由于给定的浏览器要么全部下载组合的文件,要么什么都不下载,所以永远不会出现浏览器从服务器获得一个文件的新版本,同时还从过时的浏览器缓存中获取另一个文件的旧版本的情况。此外,只维护一个主版本号要比给许多较小文件版本号更简单。
  • 压缩JS文件可以使其下载和解析更小,从而提高下载性能。
  • 如果您既要合并多个文件又要进行压缩,则压缩效果可能更好。当分别对多个小文件进行压缩时,您无法压缩在这些不同文件之间共享的变量名-它们必须保留其原始名称。但是,如果将所有JS文件组合起来,然后再进行压缩,则可以压缩在不同JS文件之间共享的所有符号(只要它们没有在外部共享)。

  • 显然,在这里有一些限制,如果全世界将它们的JS放入一个文件中,事情也不会任意地变得更好。在决定将哪些内容打包成一个文件时,应考虑以下几点:
    1. 你不希望大量页面解析和执行一个它们不会使用的代码块。这显然是个权衡问题,因为如果代码能被有效缓存,那么这就不是一个下载问题,而是运行效率问题。每个使用者都必须决定如何把这个权衡线画好。

    2. 你可能不想将经常修订的代码与几乎从不更改的代码打包在一起,因为如果大型组合JS始终在变化,这会降低浏览器缓存效率。

    3. 在团队环境中,多个项目共享代码时,非常重要的是考虑将事物打包成适用于共享代码最大数量的组合和压缩块。通常,你希望优化打包方式以满足更广泛的需求,而不只是单个项目。

    4. 移动端访问通常具有较小的缓存、较慢的CPU和较慢的连接速度,因此在打包内容时也需要考虑最常访问的移动页的需求。


    同时,组合和压缩也存在一些缺点:

    1. 直接调试压缩的站点可能会很困难,因为许多符号已经失去了有意义的名称。我发现通常需要一种方式来为调试/故障排除原因提供未压缩版本的站点(或者至少是一些文件)。

    2. 浏览器中的错误消息将指向组合/压缩文件,而不是实际的源文件,因此更难跟踪导致给定浏览器错误的代码。

    3. 必须对组合和压缩站点进行测试,以确保这些额外步骤不会引起问题。


    很棒的回答。一个想法:SourceMaps难道不会帮助解决调试问题吗?如果能提供有关它们的信息,那就更好了... - sidewinderguy
    只是好奇为什么在回答发布1.5年后还会被踩?如果踩的人能留下评论说明为什么认为它值得被踩,那么回答可以得到改进。 - jfriend00
    你能举个例子解释一下这行代码吗?因为我不太理解它的意思:"当单独压缩多个小文件时,你不能压缩在不同文件之间共享的变量名 - 它们必须保留其原始名称。但是,如果你将所有JS文件合并然后再进行压缩,你可以压缩所有在不同JS文件之间共享的符号(只要它们没有被外部共享)"。谢谢。 - Dhruv Prakash
    1
    @DhruvPrakash - 假设脚本A包含一个名为 numConnections 的全局变量, 而且被脚本B使用。如果你单独缩小每个脚本,那么在脚本A中的变量 numConnections 变成了一些简短的东西,如 Ab。但是脚本B不知道该变量名称的变化。 如果你然后压缩脚本B,就没有办法让压缩器知道如何修复脚本B中对 numConnections 的引用。如果你将它们同时压缩,那么两个脚本中所有对 numConnections 的引用都会变成相同的简短名称,一切仍然正常工作。 - jfriend00
    1
    @jfriend00 啊,我现在明白了!谢谢你。我从来没有在我的脚本中共享全局变量,所以才会感到困惑 :) - Dhruv Prakash

    4
    许多浏览器限制对特定域的并发HTTP请求数量。合并JavaScript文件可以减少需要的HTTP请求次数,使文件下载更快。
    CSS文件也是如此。
    另外,这些组合文件有时会通过缩小处理而产生具有相同语法的更小文件。
    一个缺点是,如果任何组件文件更改,整个组合文件的缓存必须被废止,并重新加载组合文件。对于大多数场景来说,这是一个非常小的缺点。

    0

    非常简单:

    1. 为了减少延迟(一个文件意味着一个HTTP GET),而浪费带宽和不必要地消耗内存资源(需要加载、解析、执行脚本,即使不需要)。
    2. 更难调试(1个导入)与更易于阅读相比。

    如果您的页面肯定会使用它们全部,则可以将它们作为一个整体加载。但这是一种粗略的过度假设,通常会崩溃。一般来说,庞大的代码库是不好的。


    合并的文件并不比未压缩的文件更难调试,但是压缩后的文件则会更加困难。 - Eric J.
    当人们合并时,通常会缩小。因此,虽然合并不是“那么”困难,但确实有一些难度。然后,当您考虑两者通常一起使用时,难度就更大了。在UI开发中,延迟是要打败的指标。 - Christian Bongiorno
    当然可以,但问题并没有涉及到代码压缩,所以在这个问题的背景下,第二点不是很合适。 - Eric J.
    好的。当然。但这是关于编程的话题。您应该始终考虑易于维护性。“话不多说 :)” - Christian Bongiorno

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接