Webpack项目优化(一)

webpack难点亮点(一遍就会)

webpack5 文档 webpack.docschina.org/concepts/#e...

一、优化1: 入口文件优化,提取公共的包

二、难点亮点2: splitChunks配置文件优化

less 复制代码
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all', // 对所有类型的块进行分割
      minSize: 20000, // 最小块大小,单位字节
      maxSize: 0, // 最大块大小,0表示不限制
      minChunks: 1, // 被引用的最小次数
      maxAsyncRequests: 30, // 最大异步请求数
      maxInitialRequests: 30, // 最大初始请求数
      automaticNameDelimiter: '~', // 自动命名的分隔符
      name: true, // 使用自动命名
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/, // 匹配 node_modules 中的模块
          name: 'vendors', // 生成的块名称
          chunks: 'all',
        },
        default: {
          minChunks: 2, // 最少引用次数
          priority: -20, // 优先级
          reuseExistingChunk: true, // 重用已存在的块
        },
      },
    },
  },
};

三、优化3: cacheGroups缓存优化

css 复制代码
a.sadas2132.js
b.adas21312.js
vendor.[hash].js

四、优化4: CDN内容分发

CDN的优化点在于,我资源没有命中缓存,需要去下载J5、css等等,才会访问CDN。

1.CDN的好处 降低服务器的压力,将压力平摊,用多台服务器顶住压力

2.用户会寻找最近的CDN服务器,减少网络延迟

业务资源和vendor资源,都可以通过cdn进行分发,提升性能

css 复制代码
a.sadas2132.js
b.adas21312.js
vendor.[hash].js

五、优化5: 浏览器缓存策略优化

在我们的项目中,大部分情况是直接使用强缓存。

协商缓存和强缓存是浏览器缓存机制中的两个重要概念,主要用于提高网页加载速度和减少服务器负担。以下是它 们的简要说明:

强缓存 强缓存是指在浏览器中直接使用缓存的资源,而不需要向服务器发送请求。强缓存的实现主要依赖于 HTTP 响应头中的 Cache-Control和Expires。

Cache-Control:这个头部可以设置缓存的策略,例如:

  • max-age=3600:表示资源可以被缓存 3600 秒(1 小时)

  • no-cache:表示强制协商缓存,即每次都要向服务器验证

  • public 或 private:指定资源是否可以被共享缓存。

Expires:这个头部指定了资源的过期时间,格式为 HTTP 日期。过期后,浏览器会向服务器请求新的资源

协商缓存

协商缓存是指在强缓存过期后,浏览器向服务器发送请求,询问资源是否被修改。协商缓存的实现主要依赖于HTTP 请求头中的 If-None-Match 和 If-Modified-since。

ETag:服务器在响应中返回的一个唯一标识符,表示资源的版本。浏览器在后续请求中会将这个标识符放在 If-None-Match 请求头中,服务器会根据这个标识符判断资源是否被修改。

Last-Modified: 服务器在响应中返回的资源最后修改时间。浏览器在后续请求中会将这个时间放在 If-Modified-since 请求头中,服务器会根据这个时间判断资源是否被修改。

总结

强缓存:直接使用缓存,不向服务器请求,依赖于Cache-Control和 Expires 。

协商缓存:在强缓存过期后,向服务器请求验证资源是否被修改,依赖于 ETag 和 Last-Modified 这两种缓存机制可以有效地减少网络请求,提高网页加载速度。

六、优化6: GZIP资源压缩优化

Js格式文件 => GZIP 格式

  1. 文本文件:对于纯文本文件(如 HTML、CSS、JavaScript),GZIP 通常可以实现 60% 到 80% 的压缩率。这意味着文件大小可以减少到原来的 20% 到 40% 左右。
  2. 图片文件:对于图像文件(如 JPEG、PNG),GZIP 的效果通常不明显,因为这些格式已经经过压缩。GZIP 可提高 5% 到 10% 的压缩率。
  3. 其他文件类型:对于某些类型的文件(如 XML、JSON、CSV),GZIP 也能提供良好的压缩效果,通常在 50% 到 90% 之间。

补充答案:GZIP 是由 webpack 打包生成的。

前端打包出来给后台的是 JS、CSS 的原始文件。

GZIP 一般是 CDN 去做,CDN 去配置,自动进行 GZIP 压缩。

前端 => 上传 aaa.js => 服务器 => 上传 CDN => CDN 将 js 转成 GZIP。
用户访问 => CDN => 返回 aaa.gzip => 浏览器解压后 => aaa.js

七、极致优化7: babel插件包体积优化

css 复制代码
module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          browsers: ["> 0.25%", "not dead"]
        }
      }
    ]
  ],
  plugins: [
    '@babel/plugin-transform-runtime'
  ]
};

Bable-core

Corejs

pollify

javascript 复制代码
JavaScript Object.assign() // es6新增的语法 => es5

a.js => a.xxxads.js (corejs assign)

b.js => b.adsaasdsad.js (corejs assign)

plugin-transform-runtime 找到我们项目中通用的corejs中的方法,放在公共部分。

八、难点8: hash粒度控制缓存优化

1.Hash

2.chunkhash 1%(基于整个chunk ex:一个组件分包)

3.contenthash 99%(基于文件 粒度最细致)

没有场景,你要强行编造场景

九、优化9: 将CSS进行单独抽离

js的内容变化,不会影响css文件,也不会影响css的hash,css可以很好的利用缓存

javascript 复制代码
// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './src/index.js', // 入口文件
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'), // 输出文件的路径
  },
  module: {
    rules: [
      {
        test: /\.css$/, // 匹配 CSS 文件
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader', // 处理 CSS 文件
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[id].css', // 输出的 chunk CSS 文件名
      chunkFilename:'[id].css',//处理的chunk 文件名
    }),
  ],
};

十、难点和亮点10: sourcemap调试优化

在 Webpack 中,Source Map 是一种用于调试的工具,它可以将编译后的代码映射回原始源代码。不同的 Source Map 配置选项会影响生成的 Source Map 的质量、大小和性能。以下是一些常见的 Source Map 配置选项及其区别:

1.source-map

  • 描述:生成完整的 Source Map 文件,适合生产环境。
  • 优点:提供完整的映射,便于调试。
  • 缺点:构建速度较慢,生成的文件较大,

2.inline-source-map

  • 描述:将 Source Map 作为 Data URL 嵌入到生成的文件中。
  • 优点:方便调试,无需额外的请求来获取 Source Map。
  • 缺点:生成的文件体积较大,适合开发环境。

3.eval-source-map

  • 描述:使用 eval()包妻每个模块的代码,并生成 Source Map.
  • 优点:构建速度快,适合开发环境。
  • 缺点:生成的 Source Map 不够完整,可能会影响性能。

4.cheap-source-map

  • 描述:生成较小的 Source Map,不包含列映射。
  • 优点:构建速度快,适合开发环境。
  • 缺点:不支持列映射,调试时可能不够精确。

5.cheap-module-source-map

  • 描述:与 cheap-source-map 类似,但支持对loader的 Source Map 进行映射
  • 优点:适合开发环境,构建速度快,
  • 缺点:同样不支持列映射。

6. hidden-source-map

  • 描述:生成 Source Map,但不在浏览器中暴露。
  • 优点:适合生产环境,可以在调试时使用,但不暴露给用户。
  • 缺点:调试时需要手动加载 Source Map.

7. nosources-source-map 描述:生成 Source Map,但不包含源代码。

  • 优点:适合生产环境,保护源代码。
  • 缺点:调试时无法查看源代码。

总结

选择合适的 Source Map 配置取决于您的开发和生产需求。 通常在开发环境中使用 eval-source-map 或 inline-source-map ,而在生产环境中使用 source-map 或 hidden-source-map 。根据项目的需求和性能 考虑,您可以选择最适合的配置,

十一、优化11: 监测webpack编译速度和性能

性能优化的前提: 我得先知道哪里慢?不是凭感觉优化。

ini 复制代码
// 性能监控
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const smp = new SpeedMeasurePlugin();

// 生成配置
const config = smp.wrap(configFactory('production'));

十二、难点亮点12: 优化js压缩混淆速度 terserPlugin

7s => 1.5s

1.开启多线程任务并行

2.AST抽象语法树进行了优化和复用

javascript 复制代码
// webpack.config.js
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  mode: 'production', // 设置为生产模式
  entry: './src/index.js', // 入口文件
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'), // 输出文件的路径
  },
  optimization: {
    minimize: true, // 启用压缩
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // 删除 console.Log
          },
          comments: false, // 不保留注释
        },
        extractComments: false, // 不提取注释到单独文件
      }),
    ],
  },
};

十三、优化13: SWC提升js、ts的编译性能

SWC(Speedy web Compiler)之所以快速,主要有以下几个原因:

1.Rust 编写:SWC 是用 Rust 编写的,Rust 是一种高性能的系统编程语言,具有优秀的内存管理和并发性能。这使得 SWC 在执行速度上优于许多用 JavaScript 或其他语言编写的编译器。

2.井行处理:SWC 支持并行处理多个文件,这意味着可以同时编译多个模块,从而显著提高构建速度,尤其是在大型项目中。

3.高效的 AST(抽象语法树)处理:SWC 在编译过程中使用高效的 AST 处理,能够快速分析和转换代码结构, 减少不必要的操作。

4.优化的编译流程:SWC 采用了优化的编译流程,能够快速进行语法分析、转换和生成代码,减少了编译过程中的开销。

5.增量编译:SWC 支持增量编译,只编译发生变化的文件,而不是每次都重新编译整个项目,这样可以大幅度减少构建时间。

6.现代特性支持:SWC 支持现代 JavaScript 和 TypeScript 特性,能够高效处理新语法,避免了对旧特性的兼容性处理,从而提高了编译速度,

通过这些设计和实现,SWC能够在保持高效性能的同时,提供快速的编译体验,适合用于现代前端开发中的构建工身

javascript 复制代码
module.exports = {
  mode: 'development', // 设置为开发模式
  entry: './src/index.ts', // 入口文件
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'), // 输出文件的路径
  },
  resolve: {
    extensions: ['.ts', '.js'], // 解析文件扩展名
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/, // 匹配 .ts 和 .tsx 文件
        exclude: /node_modules/, // 排除 node_modules 目录
        use: {
          loader: 'swc-loader',
          options: {
            jsc: {
              parser: {
                syntax: 'typescript', // 使用 TypeScript 解析
                tsx: true, // 支持 TSX
              },
              transform: {
                decoratorMetadata: true, // 启用装饰器元数据
              },
            },
          },
        },
      },
    ],
  },
};

性能提升相比babel提升了 几倍到10倍。

十四、难点解决思维14: 分析包体积,查找项目瓶颈

ini 复制代码
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

包体积的优化思路: 找主要矛盾。

十五、优化15:webpack5的原生runtime chunk优化

css 复制代码
optimization: {
  runtimeChunk: {
    name: 'runtime', // 设置 runtime chunk 的名称
  },
}

runtime.js是webpack的运行上下文。 面试吹:10k=>5k 原始包体积

优化后:

相关推荐
偷光4 分钟前
React受控组件的核心原理与实战精要
前端·javascript·react.js
录大大i38 分钟前
HTML之基本布局div|span
前端·javascript·html
sun lover2 小时前
css小知识
前端·css
阿珊和她的猫2 小时前
TypeScript 中的类:面向对象编程的基础
前端·javascript·typescript
LLLuckyGirl~3 小时前
webpack配置之---output.filename
前端·webpack·node.js
cccc☜6 小时前
echarts加载地图
前端·javascript·echarts
冰羽IOX10 小时前
Nginx部署Umi React前端项目标准配置
前端·nginx·react.js·umi·antd
恰小面包10 小时前
react的antd表格自定义图标
前端·javascript·react.js
资深前端之路10 小时前
react面试题三
前端·vue.js·react.js
明似水12 小时前
高效管理Dart和Flutter多包项目:Melos工具全解析
android·前端·flutter