为什么我的JavaScript捆绑包下载这么慢?

时间:2018-08-02 13:18:42

标签: http iis http-headers bundling-and-minification

我已将所有js库捆绑到一个大文件中,以节省大量http请求。

但是由于某些原因,下载此1.2mb软件包需要9.29秒(有时+15)。

在这种情况下,捆绑包并未缩小,但即使是捆绑包,它也需要花费4-7秒的时间才能获取783kb的内容,所以效果并不好。

但是最大的谜团是:如果我快速刷新页面5-6次,则加载时间将正常(〜150ms)。每次我刷新后,它都会保持正常。但是如果我等5分钟。并没有提出任何要求。然后加载时间又变慢了。

而且,当我在本地环境中运行应用程序时,它总是可以快速加载。

现在我对大家有两个问题:

1:将我所有的库连接到一个文件中是错误的吗?

2:在我的情况下,为什么要花近10秒钟才能下载〜1mb?

也请看一下图片,显示请求加载时间和我的请求标题

Network Tab

Request headers

2 个答案:

答案 0 :(得分:0)

  

1:将我所有的库连接到一个文件中是错误的吗?

答案:我们应该将所有库连接到单个文件中。但这应该是适当的方式。就像它在合并所有文件时不应该与任何变量冲突。您必须使用类似Gulp的缩小工具。https://www.npmjs.com/package/gulp-concat

  

2:在我的情况下,为什么要花近10秒钟才能下载〜1mb?

答案:可能无法正确缩小您的js文件。但它应该工作正常。请按照以下步骤操作:

HTTP请求是浏览器要求查看您的页面的方式。当您的网页加载到浏览器中时,浏览器会将URL中的页面发送到Web服务器的HTTP请求。然后,在交付HTML时,浏览器会对其进行解析,并寻找对图像,脚本,CSS,Flash等的其他请求。

每次看到对新元素的请求时,它都会向服务器发送另一个HTTP请求。页面具有更多请求的图像,脚本,CSS,Flash等越多,页面加载速度就越慢。减少页面上HTTP请求数量的最简单方法是不使用许多(或任何)图像,脚本,CSS,Flash等。但是仅仅是文本的页面很无聊。

如何在不破坏设计的情况下减少HTTP请求。幸运的是,有几种方法可以减少HTTP请求的数量,同时保持高质量,丰富的Web设计。

合并文件-使用外部样式表和脚本对于避免浪费页面加载时间非常重要,但不要超过一个CSS和一个脚本文件。使用CSS Sprite –将大多数或全部图像组合成一个sprite时,您会将多个图像请求变成一个。然后,您只需使用background-image CSS属性显示所需图像的部分。图像映射–图像映射不像以前那样流行,但是当您拥有连续的图像时,它们可以将多个HTTP图像请求减少到一个。使用缓存来改善内部页面的加载时间通过使用CSS精灵以及组合的CSS和脚本文件,您还可以改善内部页面的加载时间。例如,如果您有一个包含内部页面和目标页面元素的子画面图像,那么当您的读者访问这些内部页面时,该图像已经下载并位于缓存中。因此,他们也不需要HTTP请求就可以将这些图像加载到您的内部页面上。

答案 1 :(得分:0)

1:“将我的所有库连接到一个文件中是否错误?”

这里没有对与错的答案,这在很大程度上取决于捆绑包中的内容以及其使用方式(因此,我假设您通常关心负载速度)。一些想法:

通常,组合并最小化JS,CSS(和图像应合并为sprites)总是一个好主意。导线上的字节越少,传输速度就越快,更少的请求会产生更少的开销,而且成本也更低。但是...

  • 当您说“我的所有库”时,您是否包括可通过公共CDN使用的库?如果是这样,我会考虑使用这些替代方案。最终用户很有可能已经从大型/受信任的CDN(例如google)中获取了给定的文件,如果没有,则可以快速下载该文件,与您的网站加载并行,并且不花任何费用。 (如果您出于安全意识的考虑,依靠第三方来托管所需的库可能是不可接受的-但要权衡取舍并可能节省大量加载时间-取决于您所包括的库)。
  • 浏览器会限制每个主机名的请求(因此,这取决于您发出的请求总数),因此可以使用多个子域/域/ cdn来加载您的资产(id保持为1或2个其他域)。
  • 取决于您合并的库的数量以及使用的频率,仅在需要它们的页面上加载特定的库才有意义(您甚至可以在不需要它们的页面上延迟加载它们,因此它们已经被缓存了) ,但不要阻止渲染其他页面)。只需将单个页面上需要的脚本合理地移动到HTML或单独的脚本文件中,就可以提高平均页面加载速度。

2:“在我的情况下,为什么要花近10秒才能下载〜1mb?”

您自己说过-“本地环境...总是加载很快”。您的问题是数据必须经过的距离,而不是数据的打包程度。通过localhost进行访问几乎是瞬时的,但是您加载了许多脚本,通过Internet往返访问增加了建立连接的延迟。浏览器和服务器之间的“链中最慢的链接”限制了您的传输速度。

为了缩短计算机与服务器之间的距离,您应该考虑将文件缓存并托管在CDN后面。来自浏览器的请求被路由到该请求者在地理位置上本地的CDN Edge Location服务器。如果CDN先前已缓存该请求,则它立即返回(并且距离更短,因此更快)。如果CDN Edge位置尚未缓存文件,它将代表您的最终用户(通过超快速专用网络)向服务器(称为Origin)发出请求,并且如果标头允许缓存文件,文件以供将来请求。

缓存可能会导致大问题,所以我的建议是使用cache busting query string。这提供了CDN和浏览器级缓存的好处-即极大的速度提高,但仍允许您轻松更新代码并确保访问者将检索到最新版本。假设您有一个小型文件~/minified.js,则将其引用为~/minified.js?v=1(名称/值并不重要)。以后,您可以替换~/minified.js,并将标记更新为~/minified.js?v=2。这需要不缓存您实际的HTML,或者至少使用短暂的缓存,但是这意味着浏览器会将v=1v=2视为2个单独的请求,因此将下载/缓存它们。

其他一些想法:

  • 取决于应用程序,将您的javascript分成2个捆绑包可能是可行的。一个critical path脚本,它很小,下载速度很快,并且包含允许页面开始呈现的最低要求。然后是一个较大的,延迟加载的脚本,其中包含所有其他内容,这些内容将在页面加载的某个时间点以后下载。尽管这增加了传输文件的总开销,并且基本上避免了该问题,但它可能使您的页面更快地开始呈现,从而使它们“显示”得更快。另外,您可以将关键路径代码嵌入到HTML中-在初始有效负载中添加几个KB,以换取在HTML解析后即可使用的脚本。
  • CloudFlare提供了一个免费的CDN程序包-它是基本的程序,但可能适用(并包括免费的SSL)。