13个你应该知道的Webpack优化技巧

Webpack是目前前端开发最重要的构建工具。无论是自己的日常开发,还是准备面试,都应该掌握一些关于Webpack的优化技巧。

  • 在这篇文章中,我将从三个方面分享一些我常用的技巧:
    • 提高优化速度
    • 压缩打包文件的大小
    • 改善用户体验。

提高速度

线程加载器

多线程可以提高程序的效率,我们也可以在Webpack中使用。而thread-loader是一个可以在Webpack中启用多线程的加载器。

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

缓存加载器

在我们的项目开发过程中,Webpack需要多次构建项目。为了加快后续构建,我们可以使用缓存,与缓存相关的加载器是缓存加载器。

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

Hot update

当我们在项目中修改一个文件时,Webpack默认会重新构建整个项目,但这并不是必须的。我们只需要重新编译这个文件,效率更高,这种策略称为Hot update。

Webpack内置了Hot update插件,我们只需要在配置中开启Hot update即可。

const webpack = require('webpack')

// 配置
{
    deveServer: {
        hot: true
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ]
}

exclude & include

在我们的项目中,一些文件和文件夹永远不需要参与构建。所以我们可以在配置文件中指定这些文件,防止Webpack取回它们,从而提高编译效率。

当然,我们也可以指定一些文件需要编译。

exclude: 不需要编译的文件

include: 需要编译的文件

{
    test: /\.js$/,

    include: path.resolve(__dirname, '../src'),

    exclude: /node_modules/,
    use: [
        'babel-loader'
    ]
}

减小打包文件的大小

缩小 CSS 代码

css-minimizer-webpack-plugin 可以压缩和去重 CSS 代码。

npm i css-minimizer-webpack-plugin -D
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')

optimization: {
    minimizer: [
      new CssMinimizerPlugin()
    ]
}

缩小JavaScript代码

terser-webpack-plugin可以压缩和去重JavaScript代码。

npm i terser-webpack-plugin -D
const TerserPlugin = require('terser-webpack-plugin')

optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
      new TerserPlugin({
        terserOptions: {
            compress: {
                drop_console: true // remove console statement
            }
        }
      })
    ]
}

tree-shaking

tree-shaking就是:只编译实际用到的代码,不编译项目中没有用到的代码。

Webpack5中,默认情况下会启用tree-shaking。我们只需要确保在最终编译时使用生产模式。


module.exports = {
    mode: 'production'
}

source-map

当我们的代码出现bug时,source-map可以帮助我们快速定位到源代码的位置。但是这个文件很大。 为了平衡性能和准确性,我们应该:在开发模式下生成更准确(但更大)的source-map;在生产模式下生成更小(但不那么准确)的源映射。

module.exports = {
    mode: 'development',
    devtool: 'eval-cheap-module-source-map'
}
module.exports = {
    mode: 'production',
    devtool: 'nosources-source-map'
}

Bundle Analyzer

我们可以使用webpack-bundle-analyzer来查看打包后的bundle文件的体积,然后进行相应的体积优化。

npm i webpack-bundle-analyzer -D

const {
    BundleAnalyzerPlugin
} = require('webpack-bundle-analyzer')

// config
plugins: [
    new BundleAnalyzerPlugin()
]

改善用户体验

模块延迟加载

如果模块没有延迟加载,整个项目的代码会被打包成一个js文件,导致单个js文件体积非常大。那么当用户请求网页时,首屏的加载时间会更长。

使用模块懒加载后,大js文件会被分割成多个小js文件,加载时网页按需加载,大大提高了首屏的加载速度。

要启用延迟加载,我们只需要编写如下代码:


// src/router/index.js
const routes = [
    {
        path: '/login',
        name: 'login',
        component: login
    },
    {
        path: '/home',
        name: 'home',
        // lazy-load
        component: () => import('../views/home/home.vue')
    }
]

压缩包

Gzip是一种常用的文件压缩算法,可以提高传输效率。但是,此功能需要后端配合

npm i compression-webpack-plugin -D
const CompressionPlugin = require('compression-webpack-plugin')

// config
plugins: [
    // gzip
    new CompressionPlugin({
        algorithm: 'gzip',
        threshold: 10240,
        minRatio: 0.8
    })
]

base64

对于一些小图片,可以转成base64编码,这样可以减少用户的HTTP请求次数,提升用户体验。url-loader 在webpack5中已被弃用,我们可以使用assets-module代替。

{
    test: /\.(png|jpe?g|gif|svg|webp)$/,
    type: 'asset',
    parser: {
        // Conditions for converting to base64
        dataUrlCondition: {
            maxSize: 25 * 1024 // 25kb
        }
    },
    generator: {
        filename: 'images/[contenthash][ext][query]'
    }
}

正确配置哈希

我们可以将哈希添加到捆绑文件中,这样可以更轻松地处理缓存。


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

以上就是我跟你分享的13个关于Webpack的技巧,希望对你有用。

贡献者: mankueng