浅谈webpack构建优化

伴随着项目越来越大,相应的webpack的构建时间越来越久,使得我们不得不考虑性能优化的问题。如何进行分析呢?

这里列出笔者常用的工具,仅作参考

  • 时间分析:speed-measure-webpack-plugin
  • 体积分析:webpack-bundle-analyzer
src=http___img2018.cnblogs.com_blog_1282901_201904_1282901-20190429141741264-980049255.png&refer=http___img2018.cnblogs.jpeg

以下将详细介绍优化的策略

打包时间

搜索方面

  • 合理使用resolve
module.exports = {
  // ...
  resolve: {
    extensions: ['.js', '.jsx'], // 自动带上后缀查找文件
    mainFiles: ['index', 'list'],
    alias: {  // 别名,路径的映射,减少查找的范围
      alias: path.resolve(__dirname, '../src/common'),
    },
    modules: [
      path.resolve(__dirname, 'node_modules'), // 指定当前目录下的 node_modules 优先查找
      'node_modules', // 将默认写法放在后面
    ]
  },
}
  • include/exclude
const path = require('path');
module.exports = {
    //...
    module: {
        rules: [
            {
                test: /\.js[x]?$/,
                use: ['babel-loader'],
                include: [path.resolve(__dirname, 'src')],// 指定要包含的文件
                exclude: /node_modules/, // 不需要包含node_modulues 模块
                
            }
        ]
    },
}

使用缓存提升二次打包速度

将结果缓存到磁盘中,再次构建时,会进行对比,如果文件较之前的没有发送改变,则直接读取缓存)

  • 在性能消耗较大的loader之前添加==cache-loader==,将结果缓存到磁盘中。
module.exports = {
    //...
    module: {
        //项目中,babel-loader耗时比较长,所以给它配置了`cache-loader`
        rules: [
            {
                test: /\.jsx?$/,
                use: ['cache-loader','babel-loader']
            }
        ]
    }
}
  • loader开启cacheDirectory=true 缓存
module.exports = {
    //...
    new HappyPack({
      loaders: ['babel-loader?cacheDirectory=true'],
    })

}
  • 静态资源开启缓存 ==(hash, chunkhash, contenthash)==
hash:所有的文件哈希值都相同;
chunkhash:根据不同的入口文件进行依赖文件解析、构建对应的 chunk,生成对应的哈希值;
contenthash: 计算与文件内容本身相关,主要用在css抽取css文件时;
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 
module.exports = {
  mode: "production",
  entry: {
    index: "./src/index.js",
    chunk1: "./src/chunk1.js"
  },
  output: {
    filename: "[name].[chunkhash].js" // 不同的入口文件,对应不同的chunk
  },
  module: { 
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader, 
          "css-loader"
        ]
      }
    ]
  },
  plugins: [ 
    // 提取css插件
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css"  // 与文件内容本身相关联
    })
  ]
};

开启多进程

HappyPack
thread-loader(webpack4及之后推荐使用)
module.exports = {
 // ...
 module: { 
    rules: [
      {
        test: /.js$/, //对所有js后缀的文件进行编译
        use: [
          // 'babel-loader'
          'happypack/loader',
        ],
      }
    ]
  },
  plugins: [ 
    new HappyPack({
      loaders: ['babel-loader'],
    }),
  ]
}
module.exports = {
 // ...
 module: { 
    rules: [
      {
        test: /.js$/, //对所有js后缀的文件进行编译
        include: path.resolve('src'), //表示在src目录下的.js文件都要进行一下使用的loader
        use: [
          'babel-loader',
          {
            loader: 'thread-loader',
            options: {
              workers: 3,
            },
          }
        ],
    }
  ]
}

使用(动态链接库) DLLPlugin 和 DLLReferencePlugin 单独打包不经常更新的第三方库

打包体积

JS,CSS代码压缩

webpack-parallel-uglify-plugin:开始多进程压缩JS
mini-css-extract-plugin:抽离CSS,生成单独的文件
optimize-css-assets-webpack-plugin:压缩CSS文件

开启 tree-shaking(webpack4 默认开启)

静态资源压缩

对于文件使用file-loader
对于图片使用url-loader,limit属性可设置大小
module.exports = {
    // ...
    rules: [
        // ...
        {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
            // ...
            {
                loader: 'url-loader', //是指定使用的loader和loader的配置参数
                options: {
                    limit:500,  //是把小于500B的文件打成Base64的格式,写入JS
                    name: 'images/[name]_[hash:7].[ext]',
                }
            }
        ]
        }
    ]
}

splitCHunksPlugin 代码分割,抽离公共业务代码

optimization: {
  splitChunks: {
     chunks: "async", // 必须三选一: "initial" | "all"(推荐) | "async" (默认就是async)
     minSize: 30000, // 最小尺寸,30000
     minChunks: 1, // 最小 chunk ,默认1
     maxAsyncRequests: 5, // 最大异步请求数, 默认5
     maxInitialRequests : 3, // 最大初始化请求书,默认3
     automaticNameDelimiter: '~',// 打包分隔符
     name: function(){}, // 打包后的名称,此选项可接收 function
     cacheGroups:{ // 这里开始设置缓存的 chunks
         priority: 0, // 缓存组优先级
         vendor: { // key 为entry中定义的 入口名称
             chunks: "initial", // 必须三选一: "initial" | "all" | "async"(默认就是async) 
             test: /react|lodash/, // 正则规则验证,如果符合就提取 chunk
             name: "vendor", // 要缓存的 分隔出来的 chunk 名称 
             minSize: 30000,
             minChunks: 1,
             enforce: true,
             maxAsyncRequests: 5, // 最大异步请求数, 默认1
             maxInitialRequests : 3, // 最大初始化请求书,默认1
             reuseExistingChunk: true // 可设置是否重用该chunk
         }
     }
  }
 },

网络请求方面

配置externals,静态文件使用CDN加速静态资源的加载

// 在 index.html 中手动引入 cdn 链接。

// webpack.js
module.exports = {
  externals: {
    'vue': 'Vue',
    'element-ui': 'ELEMENT',
    'at-ui': 'at'
  }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇