optimization 优化

最小化

为了瘦身你的js(还有你的css,如果你用到css-loader的话)webpack支持一个简单的配置项:

--optimize-minimizeresp.new webpack.optimize.UglifyJsPlugin()

这是一种简单而有效的方法来优化你的webapp。

如果你已经阅读过我们前面的文档,我想你已经知道webpack提供了modules 和 chunks ids 来区分他们俩。利用下面的配置项,webpack就能够比对id的使用频率和分布来得出最短的id分配给使用频率高的模块:

  1. --optimize-occurence-order resp. new webpack.optimize.OccurenceOrderPlugin()

入口文件对于文件大小有较高的优先级(入口文件压缩优化率尽量的好)

去重

如果你使用了一些有着很酷的依赖树的库,那么它可能存在一些文件是重复的。webpack可以找到这些文件并去重。这保证了重复的代码不被大包到bundle文件里面去,取而代之的是运行时请求一个封装的函数。不会影响语义:

  1. --optimize-dedupe resp. new webpack.optimize.DedupePlugin()

这个功能可能会增加入口模块的一些花销

对于chunks的优化

当coding的时候,你可能已经添加了许多分割点来按需加载。但编译完了之后你发现有太多细小的模块造成了很大的HTTP损耗。幸运的是Webpack可以处理这个问题,你可以做下面两件事情来合并一些请求:

  • Limit the maximum chunk count with
    1. --optimize-max-chunks 15 new webpack.optimize.LimitChunkCountPlugin({maxChunks: 15})
  • Limit the minimum chunk size with
    1. --optimize-min-chunk-size 10000 new webpack.optimize.MinChunkSizePlugin({minChunkSize: 10000})
    Webpack通过合并来管理这些异步加载的模块(合并更多的时候发生在当前这个chunk有复用的地方)。文件只要在入口页面加载的时候没有被引入,那么就不会被合并到chunk里面去。

单页

Webpack 是为单页应用量身定做的
你可以把app拆成很多chunk,这些chunk由路由来加载。入口模块仅仅包含路由和一些库,没有别的内容。这么做在用户通过导航浏览表现很好,但是初始化页面加载的时候你需要2个网络请求:一个是请求路由,一个是加载当前内容。

如果你利用HTML5的HistoryAPI 来让URL影响当前内容页的话。你的服务器可以知道那个内容页面将被客户端请求。为了节约请求数,服务端可以把要请求的内容模块放到响应头里面:以script标签的形式来添加,浏览器将并行的加载这俩请求。

  1. <script src="entry-chunk.js" type="text/javascript" charset="utf-8"></script>
  2. <script src="3.chunk.js" type="text/javascript" charset="utf-8"></script>

你可以从build stas里面提取出chunk的filename (stats-webpack-plugin

多页

当编译一个多页面的app时,你想要在页面之间共享一些代码。这在webpack看来很简单的:只需要和多个入口文件一起编译就好

  1. webpack p1=./page1 p2=./page2 p3=./page3 [name].entry-chunk.js
  1. module.exports = {
  2. entry: {
  3. p1: "./page1",
  4. p2: "./page2",
  5. p3: "./page3"
  6. },
  7. output: {
  8. filename: "[name].entry.chunk.js"
  9. }
  10. }

由上面可以产出多个入口文件

  1. p1.entry.chunk.js, p2.entry.chunk.js and p3.entry.chunk.js

但是可以增加一个chunk来共享她们中的一些代码。
如果你的chunks有一些公用的modules,那我推荐一个很酷的插件CommonsChunkPlugin,它能辨别共用模块并把他们放倒一个文件里面去。你需要在你的页面里添加两个script标签来分别引入入口文件和共用模块文件。

  1. var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
  2. module.exports = {
  3. entry: {
  4. p1: "./page1",
  5. p2: "./page2",
  6. p3: "./page3"
  7. },
  8. output: {
  9. filename: "[name].entry.chunk.js"
  10. },
  11. plugins: [
  12. new CommonsChunkPlugin("commons.chunk.js")
  13. ]
  14. }

由上面可以产出入口文件

  1. p1.entry.chunk.js, p2.entry.chunk.js and p3.entry.chunk.js

和共用文件

  1. commons.chunk.js

在页面中要首先加载 commons.chunk.js 在加载xx.entry.chunk.js
你可以出实话很多个commons chunks ,通过选择不同的入口文件。并且你可以堆叠使用这些commons chunks

  1. var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
  2. module.exports = {
  3. entry: {
  4. p1: "./page1",
  5. p2: "./page2",
  6. p3: "./page3",
  7. ap1: "./admin/page1",
  8. ap2: "./admin/page2"
  9. },
  10. output: {
  11. filename: "[name].js"
  12. },
  13. plugins: [
  14. new CommonsChunkPlugin("admin-commons.js", ["ap1", "ap2"]),
  15. new CommonsChunkPlugin("commons.js", ["p1", "p2", "admin-commons.js"])
  16. ]
  17. };
  18. // <script>s required:
  19. // page1.html: commons.js, p1.js
  20. // page2.html: commons.js, p2.js
  21. // page3.html: p3.js
  22. // admin-page1.html: commons.js, admin-commons.js, ap1.js
  23. // admin-page2.html: commons.js, admin-commons.js, ap2.js

另外你可以将多个共用文件打包到一个共用文件中。

  1. var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
  2. module.exports = {
  3. entry: {
  4. p1: "./page1",
  5. p2: "./page2",
  6. commons: "./entry-for-the-commons-chunk"
  7. },
  8. plugins: [
  9. new CommonsChunkPlugin("commons", "commons.js")
  10. ]
  11. };

更多有关共用模块打包,可以看看: multiple-entry-points example 以及 advanced multiple-commons-chunks example