最全 webpak4.0 打包性能优化清单

最全 webpak4.0 打包性能优化清单

webpack4.0如何进行打包优化?

无非是从两个角度进行优化,其一:优化打包速度,其二:优化打包体积,送你一份打包性能优化清单

1.使用loader的时候尽量指定exclude和inlucde来提高文件查找效率,避免不必要的查找,设置noParse参数

module: {
    noParse: /jquery/, // 不去解析jquery中的依赖
    rules:[
        {
            test: /\.js?$/, 
            use: [
                { loader: 'babel-loader' },
                {
                    // 自定义的同步处理loader
                    loader: 'replaceLoader',
                    options: {
                        name: 'hellonew'
                    }
                },
                {
                    // 自定义的异步处理loader
                    loader: 'asyncReplaceLoader',
                    options: {
                        name: 'myloader'
                    }
                }
            ],
            exclude: ['/node_modules'],
            include: [path.resolve(__dirname, '../src/asset/less/component/js')]
        }
    ]
},

2.对css公共的模块进行分离

const CssMiniExtreactPlugin = require('mini-css-extract-plugin')
// postcss自动给css3加上前缀
module{
    rules:[
        {
           test: /\.less?$/,
                // loader的执行顺序,从下到上,从右到左
                use: [
                    {
                        loader: CssMiniExtreactPlugin.loader,
                        options: {
                            publicPath: '../'
                        }
                    },
                    {
                        // css-loader
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2 // import引入的less文件也执行less-loader
                            // modules: true
                            // minimize: true
                        }
                    },
                    'postcss-loader',
                    'less-loader'
                ]
        }
    ]
}
plugins:[
     new CssMiniExtreactPlugin({
            filename: 'css/[name]_[contenthash].css',
            chunkFilename: 'css/[name]_chunk_[contenthash].css'
     }),
],
optimization: {
    //拆分css,公共的使用过两次的chunk打包到common.css方便做缓存,单独的css每个页面打包一个针对当前的页面的css
    splitChunks: {
            name: true,
            cacheGroups: {
                // 打包公共的css
                styles: {
                    name: 'common',
                    test: /\.less$/,
                    chunks: 'all',
                    enforce: true,
                    minChunks: 2
                },
                // 打包每个页面的css
                fooStyles: {
                    name: 'index',
                    test: (m, c, entry = 'index') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
                    chunks: 'all',
                    enforce: true
                },
                barStyles: {
                    name: 'detail',
                    test: (m, c, entry = 'detail') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
                    chunks: 'all',
                    enforce: true
                },
            }
        }
    }
}

3.拆分js,将公共的js拆分方便把相同的内容缓存下来

// 配置splitChunks
optimization: {
    splitChunks: {
        name: true,
        cacheGroups: {
            vendors: {
                chunks: 'async',
                name: 'verdon',
                test: /[\\/]node_modules[\\/]/,
                priority: -20,
                minSize: 0
                // filename: '[name].js'
            },
            default: {
                chunks: 'all',
                name: 'common',
                minChunks: 1,
                test: /[\\/]node_modules[\\/]/, // 配置打包哪里的文件
                priority: -10
                // reuseExistingChunk: true
            }
        }
    }
}

4.开启css,js和html压缩

//压缩css
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
plugins:[
    new OptimizeCssAssetsWebpackPlugin()
]
//压缩js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
optimization: {
    minimizer: [
        new UglifyJsPlugin({
            cache: true,
            parallel: true, // 并发压缩
            sourceMap: true // 开启sourcemap
        })
    ]
}
//压缩html
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins:[
    new HtmlWebpackPlugin({
        hash: true,
        template: `./src/index.html`,
        filename: `index.html`,
        minify: {
            collapseWhitespace: true   //开启html压缩
        }
    })
]

5.使用tree shake把没有用到的js和css剔除掉

optimization: {
    usedExports: true, // 使用tree shake
}
//需要在package.json里面设置“sideEffect”进行配合使用 
"sideEffects": [
    "*.css",           //移出css
    "@babel/polyfill"  //移除掉@babel/polyfill
],

6.善用alias,resolve里面有一个alias的配置项目,能够让开发者指定一些模块的引用路径。

// 省略后缀
resolve: {
     extensions: ['.js', '.vue', '.jsx', '.json'],
     // 定义别名
     alias: {
     '@component': utils.resolve('../src/component')
     }
},

7.使用prefetch预加载

// 异步加载
function dom() {
    return import(/* webpackPrefetch:true */ 'lodash').then(({ default: _ }) => {
        let div = $('<div>')
        div.html(_.join(['webpack', 'is', 'so', 'easy'], '***'))
        return div
    })
}

8.使用懒加载

//配置babel
npm install @babel/plugin-syntax-dynamic-import -D
//.babelrc文件配置如下
{
    "plugins": ["@babel/plugin-syntax-dynamic-import"]
} 
//在项目中正常使用即可
const Foo = () => import('./Foo.vue')

9.使用DllPlugin使得第三方模块只打包分析一次

//生成一个webpack.dll.config.js文件,执行npm run dll
const utils = require('./utils')
const webpack = require('webpack')
module.exports = {
    mode: 'production',
    entry: {
        jquery: ['jquery'],
        lodash: ['lodash']
    },
    output: {
        path: utils.resolve('../dll'),
        filename: '[name].dll.js',
        library: '[name]' // 将打包的dll文件暴露一个公共的变量
    },
    plugins: [
        // 输出映射关系
        new webpack.DllPlugin({
            name: '[name]',
            path: utils.resolve('../dll/[name].manifest.json')
        })
    ]
}
//以下为webpack配置
new AddAssetWebpackPlugin({
    filepath: utils.resolve('../dll/jquery.dll.js')
}),
    new AddAssetWebpackPlugin({
    filepath: utils.resolve('../dll/lodash.dll.js')
}),
    new webpack.DllReferencePlugin({
    manifest: utils.resolve('../dll/jquery.manifest.json')
}),
    new webpack.DllReferencePlugin({
    manifest: utils.resolve('../dll/lodash.manifest.json')
})

10.使用happyPack进行多线程打包,提升打包效率

//npm install happypack -D
const Happypack = require('happypack') // 多线程打包,提高打包速度
let os = require('os')
let happyThreadPool = Happypack.ThreadPool({ size: os.cpus().length })

//webpack.config.js配置
rules:[
    {
        test:/\.less?$/
        use:['happypack/loader?id=css']
    }
    {
         test: /\.js?$/,
         use: ['Happypack/loader?id=js'],
    }
]
plugins:[
    new Happypack({
       id:'css',
       use:['style-loader','css-loader','less-loader'],
       threadPool: happyThreadPool
    }),
    new Happypack({
        id: 'js',
        use: [
            { loader: 'babel-loader' },
            {
                loader: 'replaceLoader',
                options: {
                    name: 'hellonew'
                }
            },
            {
                loader: 'asyncReplaceLoader',
                options: {
                    name: 'wxl'
                }
            }
        ],
        threadPool: happyThreadPool
    })
]

11.对图片打包,适当采用base64位格式,如css sprite图片可以使用base64位格式

rules:[
     {
         test: /\.(jpg|png|svg|gif)?$/,
         use: {
             // loader: 'file-loader',
             loader: 'url-loader', // url-loader把图片打包成base64格式了
             options: {
                 // placeholder
                 name: '[name]_[hash].[ext]',
                 outputPath: 'images/', // 将图片打包到指定的文件夹下
                 limit: 204800 // 小于限定尺寸图片就被打包到images目录下
             }
         }
     }
]

12.合理使用devtool参数,开发环境不建议使用cheap-module-source-map

devtool: 'cheap-module-source-map',

13.使用image-webpack-loader压缩图片,适当设置压缩程度,以免造成图片失真

$ npm install image-webpack-loader --save-dev
 {
         loader: 'image-webpack-loader',
         options: {
             mozjpeg: {
                  progressive: true,
                  quality: 65
             },
             optipng: {
                  enabled: true
             },
             pngquant: {
                  quality: [0.65, 0.90],
                  speed: 4
             },
             gifsicle: {
                  interlaced: false
             },
             webp: {
                  quality: 75
             }
        }
}

相关推荐