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 原始包体积

优化后:

相关推荐
再吃一根胡萝卜7 小时前
08 · 前端:Vue3 + SSE 流式与执行链路可视化
面试
再吃一根胡萝卜7 小时前
03 · 后端:FastAPI 与分层架构
面试
mldong8 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排9 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby606110 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角11 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!11 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰11 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
Interview Aid11211 小时前
Walmart Global Tech SDE 三轮面经|基础、并发、压力面
面试·职场和发展
mayaairi12 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js