• 最全 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
                 }
            }
    }
    
  • 相关阅读:
    react + iscroll5 实现完美 下拉刷新,上拉加载
    Masuit.Tools:C#硬核开源工具库!
    react 下拉刷新上拉加载更多通用组件
    前端必备基础知识:window.location 详解
    浅谈流媒体
    ThinkPad P15v:专业移动工作站,表现如何?
    react 上拉加载组件的使用
    说一说前端路由与后端路由的区别
    主流开源流媒体服务器有哪些?(转)
    15个有用的React动画库,马上让你的项目变得高大上
  • 原文地址:https://www.cnblogs.com/xinggood/p/11996921.html
Copyright © 2020-2023  润新知