webpack优化

164 阅读4分钟

为什么需要webpack优化?

伴随着项目的时间推移,体积越来越大,构建时间、打包体积这些都需要优化

构建时间的优化

1. 多进程优化 thread-loader

可以开启多进程打包,这样能大大提高项目的构建速度,怎么样使用,只需要将thread-loader放在比较费时间的loader之前,比如babel-loader

这样一来项目的启动速度和打包速度都能得到提升

npm i thread-loader -D

    { 
        test: /\.js$/, 
        use: [ 'thread-loader', 'babel-loader' ], 
        } 
    }
    

2.热更新的开启

假如你修改了项目中的某一个文件,这样整个项目都会刷新,这是非常耗时的,但是我们能做到只刷新我们修改这个模块,其他保持原来的状态,那么在修改代码的构建时间方面是不是就大大提升了呢

怎么做?

// xxx.webpack.js
const {HotModuleReplacementPlugin} = require('webpack');  // 该插件是webpack自带的

plugins: [ 
    new HotModuleReplacementPlugin() 
], 

//最后需要在我们的devserver中配置 
devServer: { 
    hot: true 
},

3.exclude

一般用于排除不需要处理的文件,例如node_modules

    { 
        test: /\.js|x$/,  
        include: path.resolve(__dirname, '../src'), 
        exclude: /node_modules/, 
        use: [ 
            'thread-loader',
            'babel-loader'
        ]
    },

4.使用gzip

主要准对开发环境,使用gzip中的体积优化配置,这能让最终的项目打包体积大大减低

最后如果能对webpack的版本进行升级是最好的,这对项目上线之后的页面加载速度都能得到提升的

优化打包体积(以下出现的配置都是在开发环境)

这个主要是对项目整体的体积进行优化,更多是为了提高项目上线之后的页面加载速度提升

1.css的代码压缩

npm i css-minimizer-webpack-plugin -D

功能:可以起到代码压缩、去重, 如何配置?

    const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
    optimization: { 
        minimizer: [ 
            new CssMinimizerPlugin(), // 去重压缩css, 同时也进行了压缩
        ], 
    }

2.js的代码压缩

npm i terser-webpack-plugin -D

怎样配置?

    const TerserPlugin = require('terser-webpack-plugin')
    optimization: { 
        minimizer: [ 
            new CssMinimizerPlugin(), // 去重压缩css 
            new TerserPlugin({ // 压缩JS代码 
            terserOptions: { 
                compress: { 
                    drop_console: true, // 删除代码中console }, 
                }, 
            }), 
        ], 
    }

3.开启tree-shaking

tree-shaking简单来说就是把一颗树上没有用的叶子给摇掉,在代码中就是只打包用到的代码,而webpack5中默认就开启了tree-shaking, 只需要把mode设置为production是,就能自动开启three-shaking了,详细在这里有介绍juejin.cn/post/709502…

4.选择不同的source-map类型

source-map的作用是:方便你报错的时候能定位到错误代码的位置。当然它的体积也是不能小看的,所以对于不同环境应当选择不同的类型

  1. 开发环境我们是需要能够精确能够定位到错误代码的位置的
    module.exports = { 
        mode: 'development', 
        devtool: 'eval-cheap-module-source-map' 
    }
  1. 生产环境,我们既想要开启source-map, 但是又不想打包体积太大,这时候可以选择 nosources-source-map
    module.exports = { 
        mode: 'production', 
        devtool: 'nosources-source-map' 
    }

需要优化肯定是离不开对项目打包体积的分析

npm i webpack-bundle-analyzer -D

    // xxx.webpack.prd.js
    const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') 
    plugins: [ 
        new BundleAnalyzerPlugin(), 
    ]

用户使用体验优化

1.使用模块懒加载

假设我们不使用懒加载,这样会把整个项目的代码都打包到一个js文件里面,随之单个js文件的体积就会非常庞大,此时就会出现网页请求的时候首屏加载时间长的问题,使用模块懒加载之后,就会把大的js文件拆分成小的js文件,在加载网页的时候就会实现按需加载,同时首屏加载的时间也会大大提升

    // vue
    const routes = [ 
        { 
            path: '/login', 
            name: 'login', 
            component: login 
        }, 
        { 
            path: '/home',
            name: 'home', 
            // 懒加载 component: () => import('../views/home/home.vue'), 
        },
    ]
    // React
    import React, { Suspense,lazy } from 'react';
    const Reg = lazy(()=>import('./views/Reg'));
    const Login = lazy(()=>import('./views/Login'));
    <Suspense fallback={<div>loading...</div>}>
      {/* 路由配置 */}  
      <Switch>
        <Route path="/reg" component={Reg}/>
        <Route path="/login" component={Login} />
      </Switch> 
    </Suspense>

2.Gzip开启

有什么用? 为了实现减少项目体积, 对比之下会发现gzip的提交会比原文件小的多了,当然这也是需要后端配合的

怎么做?

npm i compression-webpack-plugin -D

    // xxx.webpack.prd.js
    const CompressionPlugin = require('compression-webpack-plugin') 
    plugins: [ 
        // gzip 
        new CompressionPlugin({ algorithm: 'gzip', threshold: 10240, minRatio: 0.8 }) 
    ]

3.小图片、图标转base64

base64可以让网络请求次数减少,提高用户的体验 webpack5url-loader已被废弃,改用asset-module

怎么做?

    { 
        test: /\.(png|jpe?g|gif|svg|webp)$/, 
        type: 'asset', 
        parser: { 
            // 转base64的条件 
            dataUrlCondition: { 
                maxSize: 25 * 1024, 
                // 小于25kb 
            } 
        }, 
        generator: { 
        // 打包到 img 文件下 
        filename: 'img/[contenthash][ext][query]', 
        }, 
    },

4.hash选择(contenthash)

这样能让有改动过的文件更新hash, 没有改动过的文件hash保持,等到上线之后,浏览器在访问的时候没有改动过的文件就会命中缓存,从而优化了性能

    output: { 
        path: path.resolve(__dirname, '../dist'), 
        // 给js文件加上 contenthash 
        filename: 'js/chunk-[contenthash].js', clean: true, 
    },