HTTP单个大文件与拆分小文件的资源加载对比

刷到一篇很有趣的文章《The Three Cs: Concatenate, Compress, Cache》,从不同角度对比单文件与拆分小文件的页面加载速度,同时也得出了几个反直觉的结论:

结论1:在HTTP2中,单个大文件的下载及渲染速度比拆分多个小文件更快

使用单个大文件的CSS渲染页面,单个CSS文件(18.4KB)总计花了1094ms来加载(其中累积延迟 201ms,加载耗时 109ms)。而加载拆分后的12个小CSS(60KB)加载则花费了1524ms(其中累积延迟 4362ms,加载耗时 240ms)。相比增加了1.4-3.3倍的耗时。
单个文件加载单个文件加载

拆分后多个小文件加载拆分后多个小文件加载

结论二:在低压缩或不压缩时,多个小文件比一个大文件的加载速度快;在使用Gzip、Brotli压缩后,一个大文件比多个小文加的加载速度快得多。

结论三:所有附带hash签名的静态文件都可以增加缓存Header,但单个大文件更容易出现缓存失效的情况。

虽然经过压缩的大文件加载速度更快,但是由于大文件自身聚合了过多资源,任一资源的内容变更都会导致整个文件hash发送变化,以至于缓存失效。因此,我们需要配置尽可能少的大文件捆绑包来充分利用压缩和调度,但同时也需要足够多的小文件来适应代码库的高更改率,从而达到最优的缓存策略,这是一种十分关键的权衡

结论四:即使在各种网络条件下,压缩过的大文件加载速度都比其他小文件(或未压缩的文件)快得多

这里还得出几个结论:

  • 压缩的有效性随着网络连接速度的增加而降低,但在低网速的情况下,无压缩与任意压缩的差距都是巨大的。
  • 只要压缩一个大文件,在任何网络连接速度下都会更快。
  • Gzip的单文件比一堆小文件加载速度快一点,而Brotli 上的单文件比一堆小文件快的多。

结论五:在浏览器中,单个大文件的解析和编译时间更长,但执行速度不一定更慢

举个例子:一个2.4M的Js文件,在移动设备中进行编译只需10ms,远小于文件的下载时间。

结尾:几个建议

  • 对于不必要的代码,不发送给客户端比压缩其体积更好。
  • 如果仍在使用HTTP1.1,建议升级至HTTP2。
  • 如果静态资源之前从未进行压缩,那就立刻马上进行。
  • 如果你还在使用Gzip,那建议升级至Brotli。
  • 一旦你使用了Brotli,选择单个大文件的资源捆绑包会更适合。

评论区