webpack & HTTP/2

webpack & HTTP/2

让咱们从 HTTP/2 的一个传言开始:前端

有了 HTTP/2,你就再也不须要打包模块了。react

HTTP/2 能够多路复用,全部模块均可以并行使用同一个链接,所以多个请求再也不须要多余的往返开销。每一个模块均可以独立缓存。android

很遗憾,现实并不如意。webpack

之前的文章

下面的文章详细解释了相关信息,而且作了一些实验来验证。你能够阅读它们(或者跳过它们,只看总结)。ios

Forgo JS packaging? Not so fast The traditional advice for web developers is to bundle the JavaScript files used by their webpages into one or (at most…engineering.khanacademy.orggit

The Right Way to Bundle Your Assets for Faster Sites over HTTP/2 Speed is always a priority in web development. With the introduction of HTTP/2, we can have increased performance for a…medium.comgithub

文章主旨:web

  • 相比拼接为一个文件,多个文件传输仍然有 协议开销(protocol overhead)
  • 相比多个小文件,单文件方式对压缩更友好。
  • 相比处理单个大文件,服务器处理多个小文件较慢。

所以咱们须要在二者中间取得一个折中。咱们将模块分为 n 个包,n 大于 1,小于模块数。改变其中一个模块使其缓存失效,由于相应的包只是整个应用的一部分,其它的包的缓存仍然有效。后端

更多的包意味着缓存命中率更高,但不利于压缩。浏览器

AggressiveSplittingPlugin

webpack 2 为你提供了这样的工具。webpack 内部大多都是这样,将一组模块组装成块(chunk)输出一个文件。咱们还有一个优化阶段能够改变这些块(chunk),只是须要一个插件来作这个优化。

插件 AggressiveSplittingPlugin 将原始的块分的更小。你能够指定你想要的块大小。它提升了缓存,但不利于压缩(对 HTTP/1 来讲也影响传输时间)。

为告终合类似的模块,它们在分离以前会按照路径的字母顺序排序。一般在同一目录下的文件每每是相关的,从压缩来看也是同样。经过这种排序,它们也就能分离到相同的块中了。

对于 HTTP/2 咱们如今有高效的分块方式了。

修改应用

但这还没结束。当应用更新时咱们要尽可能复用以前建立的块。所以每次 AggressiveSplittingPlugin 都可以找到一个合适的块大小(在限制内),并将块的模块(modules)和哈希(hash)保存到 records 中。

Records 是 webpack 编译过程当中编译状态的概念,能够经过 JSON 文件存取。

当再次调用 AggressiveSplittingPlugin,在尝试分离剩余模块以前,它会先尝试从 records恢复块。这就确保已缓存的块可以被复用。

启动和服务(Bootstrapping and Server)

使用这项技术的应用再也不输出包含在 HTML 文件中的单独文件,相反,它输出多个须要被加载的块(chunk),应用就能使用多个 script 标签(并行)加载每一个块。就像这样:

<script src="1ea296932eacbe248905.js"></script>
<script src="0b3a074667143853404c.js"></script>
<script src="0dd8c061aff2a2791815.js"></script>
<script src="191b812fa5f7504151f7.js"></script>
<script src="08702f45497539ef6ea6.js"></script>
<script src="195c9326275620b0e9c2.js"></script>
<script src="19817b3a0378aedb2143.js"></script>
<script src="0e7a65e649387d773247.js"></script>
<script src="13167c9702de79d2f4fd.js"></script>
<script src="1154be40ff0e8dd16e9f.js"></script>
<script src="129ce3c198a25d9ace74.js"></script>
<script src="032d1fc9a213dfaf2c79.js"></script>
<script src="07df084bbafc95c1df47.js"></script>
<script src="15c45a570bb174ae448e.js"></script>
<script src="02099ada43bbf02a9f73.js"></script>
<script src="17bc99aaed6b9a23da78.js"></script>
<script src="02d127598b1c99dcd2d0.js"></script>复制代码

webpack按时间前后顺序输出这些块。最旧的文件先执行,最新的在最后。浏览器能够先执行已被缓存的块,同时加载最新的文件 -- 旧文件更可能已经被缓存。

当 HTML 文件被请求时,HTTP/2 服务端推送能够将这些块推送给客户端。也是由于旧文件更可能已经被缓存,最好能先推送最新的文件。若是已经有缓存,客户端能够取消服务端的推送,但这须要一次往返。

webpack 将代码分离用于 按需加载,能够处理并行请求。

结论

webpack 2 为你提供了用于 HTTP/2 的,能改善缓存和传输的工具。不用担忧你的技术栈不面向将来了。

注意 AggressiveSplittingPlugin 仍然是实验特性

我对你的使用体验很感兴趣哦~


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOSReact前端后端产品设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索