• Webpack性能调优:从加载器到插件的全面优化


    Webpack 是一个模块打包工具,它将项目中的各种资源(JavaScript、CSS、图片等)转换成一个或多个浏览器可识别的输出文件。优化 Webpack 的性能主要涉及减少构建时间、减小输出文件大小和提高应用加载速度。

    2500G计算机入门到高级架构师开发资料超级大礼包免费送!

    模块分割(Code Splitting)

    使用 import() 动态导入或者 webpack.optimize.SplitChunksPlugin 来拆分代码,将不常使用的模块或库分离到单独的 chunk 中,只在需要时加载,从而减少初始加载时间。

    // 动态导入示例
    let module = () => import('./module.js');
    

    Tree Shaking

    Webpack 4 及以上版本支持 ES6 模块的 Tree Shaking,通过静态分析移除未使用的代码。确保使用 import 而不是 require,并且避免副作用导入。

    // 不利于 Tree Shaking
    var _unusedFunction = require('library').unusedFunction;
    
    // 有利于 Tree Shaking
    import { usedFunction } from 'library';
    

    懒加载(Lazy Loading)

    对于大型单页应用,可以使用懒加载组件,只在用户导航到相应路由时才加载。

    // 使用React Router的懒加载示例
    import React, { lazy, Suspense } from 'react';
    const LazyComponent = lazy(() => import('./LazyComponent'));
    
    // 在路由配置中
    <Route path="/lazy" component={LazyComponent} />
    

    压缩和混淆(Minification & Obfuscation)

    使用 UglifyJS 或 Terser 插件压缩和混淆代码,以减小输出文件大小。

    // 在webpack配置中
    const TerserPlugin = require('terser-webpack-plugin');
    
    module.exports = {
      // ...
      optimization: {
        minimize: true,
        minimizer: [new TerserPlugin()],
      },
    };
    

    声明文件(Declaration Files)

    为 TypeScript 库提供类型声明文件,以便 Webpack 可以进行类型检查和优化。

    模块解析(Resolve)

    优化模块解析规则,减少查找模块的时间。

    module.exports = {
      // ...
      resolve: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
        alias: {
          '@components': path.resolve(__dirname, 'src/components'),
        },
      },
    };
    

    缓存(Cache)

    利用 hard-source-plugin 或 cache-loader 缓存编译结果,加快二次构建速度。

    // 在webpack配置中
    const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
    
    module.exports = {
      // ...
      plugins: [
        new HardSourceWebpackPlugin(),
      ],
    };
    

    图片和字体图标处理

    使用 url-loader 或 file-loader 处理图片和字体图标,将小文件内联到 CSS 或 JavaScript 中,大文件则单独打包。

    module.exports = {
      // ...
      module: {
        rules: [
          {
            test: /\.(png|jpg|gif)$/,
            use: [
              {
                loader: 'url-loader',
                options: {
                  limit: 8192, // 小于8KB的图片会被base64编码
                },
              },
            ],
          },
        ],
      },
    };
    

    源映射(Source Maps)

    在开发环境中启用源映射 (devtool: 'source-map'),便于调试,而在生产环境中可以选择更高效的映射类型,如 'cheap-module-source-map',以减小打包后的文件大小。

    module.exports = {
      // ...
      devtool: process.env.NODE_ENV === 'production' ? 'cheap-module-source-map' : 'source-map',
    };
    

    避免重复打包(Dedupe)

    使用 webpack.DedupePlugin(在 Webpack 4 中已弃用,但可以通过其他方式实现)或 terser-webpack-plugin 的 terserOptions 来删除重复的模块。

    优化 CSS 和 SVG

    使用 mini-css-extract-plugin 提取 CSS 到单独文件,便于缓存。
    对 CSS 进行预处理(如 SCSS、LESS)和后处理(如 Autoprefixer)。
    使用 svg-sprite-loader 或 svg-url-loader 优化 SVG 图标。

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    module.exports = {
      // ...
      module: {
        rules: [
          {
            test: /\.scss$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
          },
          {
            test: /\.svg$/,
            use: ['svg-url-loader'],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: '[name].css',
          chunkFilename: '[id].css',
        }),
      ],
    };
    

    预加载和预读取(Preloading & Prefetching)

    使用 HTML 标签,提前加载资源。

    
    <link rel="preload" href="/fonts/my-font.woff2" as="font" crossorigin>
    <link rel="prefetch" href="/images/large-image.jpg">
    

    开启多进程(Parallel Processing)

    使用 thread-loaderworker-loader 利用多核处理器并行处理任务。

    module.exports = {
      // ...
      module: {
        rules: [
          {
            test: /\.js$/,
            enforce: 'pre',
            use: 'thread-loader',
          },
        ],
      },
    };
    

    自定义 Webpack DevServer

    根据项目需求定制 webpack-dev-server 的配置,例如开启热模块替换 (HMR)、调整代理设置等。

    module.exports = {
      // ...
      devServer: {
        hot: true,
        proxy: {
          '/api': {
            target: 'http://api.example.com',
            secure: false,
          },
        },
      },
    };
    

    优化外部依赖

    将第三方库作为外部依赖处理,避免重复打包,尤其是大型库。这可以通过 externals 配置实现。

    module.exports = {
      // ...
      externals: {
        react: 'React',
        'react-dom': 'ReactDOM',
      },
    };
    

    分离公共模块(Common Chunks)

    使用 webpack.optimize.CommonsChunkPlugin(在 Webpack 4 中被 SplitChunksPlugin 替代)提取共用模块,减少重复代码,加速页面加载。

    module.exports = {
      // ...
      optimization: {
        runtimeChunk: 'single',
        splitChunks: {
          chunks: 'all',
          minSize: 10000,
          maxSize: 0,
          minChunks: 1,
          maxAsyncRequests: 5,
          maxInitialRequests: 3,
          automaticNameDelimiter: '~',
          name: true,
          cacheGroups: {
            vendors: {
              test: /[\\/]node_modules[\\/]/,
              priority: -10,
              filename: 'vendors.js',
            },
            default: {
              minChunks: 2,
              priority: -20,
              reuseExistingChunk: true,
              filename: 'common.js',
            },
          },
        },
      },
    };
    

    模块合并(Module Concatenation)

    启用 ModuleConcatenationPlugin 以实现模块间的内联和重用,减少输出文件数量和大小。

    const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
    
    module.exports = {
      // ...
      plugins: [
        new ModuleConcatenationPlugin(),
      ],
    };
    

    优化 Loader 配置

    对于 CSS,使用 css-loaderimportLoaders 参数控制预处理器的顺序。
    使用 postcss-loader 添加自动前缀,简化 CSS 代码。
    对于图片,使用 image-webpack-loader 进行压缩。

    module.exports = {
      // ...
      module: {
        rules: [
          {
            test: /\.css$/,
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader?importLoaders=1', // 1 表示1个前置的loader,这里是postcss-loader
              'postcss-loader',
            ],
          },
          {
            test: /\.(png|jpe?g|gif)$/i,
            use: [
              {
                loader: 'file-loader',
                options: {},
              },
              {
                loader: 'image-webpack-loader',
                options: {
                  mozjpeg: {
                    progressive: true,
                  },
                  gifsicle: {
                    interlaced: false,
                  },
                  optipng: {
                    optimizationLevel: 7,
                  },
                  pngquant: {
                    quality: '75-90',
                    speed: 4,
                  },
                },
              },
            ],
          },
        ],
      },
    };
    

    代码覆盖率报告

    在测试阶段,使用 istanbul-instrumenter-loader 计算代码覆盖率。

    module.exports = {
      // ...
      module: {
        rules: [
          // ...
          {
            test: /\.js$/,
            enforce: 'post',
            include: /src/,
            use: [{
              loader: 'istanbul-instrumenter-loader',
              options: { esModules: true },
            }],
            exclude: [/node_modules/, /\.spec\.js$/],
          },
        ],
      },
    };
    

    自动部署与监控

    集成 CI/CD 工具,如 Jenkins、Travis CI 或 CircleCI,自动化构建、测试和部署流程。同时,使用工具如 Sentry 或 New Relic 监控应用性能。

    2500G计算机入门到高级架构师开发资料超级大礼包免费送!

  • 相关阅读:
    【Unity Material】02 - Material使用技巧
    uniCloud云开发获取小程序用户openid
    Debian 11 AMD Install driver(wifi...)
    Hive学习笔记(3)——DML数据操作
    Linux安装kafka-manager
    5个 GIS空间分析 空间查询与量算 的重要知识点
    如何解决分布式Session共享的问题
    为什么要引入线程?
    基于Git和Jenkins企业级自动化测试及部署实例,附详细截图和完整代码
    npm install的--save和--save-dev使用说明
  • 原文地址:https://blog.csdn.net/A1215383843/article/details/139247975