当前位置: 首页 > article >正文

webpack打包体积优化,减少白屏时间

webpack打包体积优化

加载慢原因分析及解决

一个是打包体积的优化,另一个是代码层面的优化

1》首先通过Network面板发现vendor.js体积过大,网路良好情况下加载时间太长),vendor体积太大,加载花了3s?后来发现 js 没开启nginx压缩

2》通过 webpack-bundle-analyzer 来具体分析,进一步体积过大的原因,进一步进行打包优化

打包体积优化方案

1》开启gzip压缩

压缩原理:简单的理解就是将相同的内容,用两者之间的距离和相同内容的长度来替换后面的内容,从而使整个文件变小。所以文件中代码的重复率越高,那么压缩的效率就越高,使用 gzip 的收益也就越大

如何判断是否开启

请求头:服务端会通过客户端发送的请求头中的 Accept-Encoding 字段来确定是否支持

Accept-Encoding:gzip, deflate, br

响应头:表示当前资源会使用 gzip 压缩,提示客户端解压使用。

Content-Encoding:gzip

nginx中开启gzip

http {
  gzip on;
  gzip_types text/plain text/css application/json application/javascript text/xml       application/xml application/xml+rss text/javascript;
}
属性说明
gzipon/off,是否开启gzip压缩
gzip_types压缩哪些文件类型
gzip_min_lengtheg:10k;大于10k的文件才会进行压缩(小于10k可能压缩后反而变大)
gzip_buffers获取多少内存用于缓存压缩结果,eg: 16 8k 表示使用16个缓冲区,每个缓冲区大小为8KB
gzip_comp_level压缩比(1~9),越小压缩效果越差,但是越大处理越慢,所以一般取中间值
gzip_static on优先匹配 gzip 文件来返回,如果没有就寻找相应资源进行 gzip 压缩再返回

优点:减小文件体积,页面加载更快

缺点:开启 gzip 后会额外的增加很多 cpu 的开销,会对服务器产生一定压力,(客户端解压也需要cpu开销不过客户端还好),这也是不建议把压缩率设置太高的原因。另外,对图片的压缩支持不太好,会出现体积变大或图片失真的问题

webpack开启gzip打包

通过插件compression-webpack-plugin来生成.gz文件

npm i -D compression-webpack-plugin

webpack增加配置

// 最好是先判断以下环境变量是否是生产环境的打包
const CompressionWebpackPlugin = require('compression-webpack-plugin')
if (process.env.NODE_ENV === 'production') {
    webpackConfig.plugins.push(
    	new CompressionWebpackPlugin({
            filename: '[path].gz[query]',
            // 目标资源名称。 [file] 会被替换成原始资源。[path] 会被替换成原始资源的路径, [query] 会被替换成查询字符串。默认值是 "[path].gz[query]"。
            algorithm: 'gzip',
            // 算法,默认'gzip'
            test: '\\.(js|css))$',
            // 所有匹配该正则的资源都会被处理。默认值是全部资源。
            // 这里只匹配了js、css文件
            threshold: 10240,
          	//只有大小大于该值的资源会被处理。单位是 bytes。默认值是 0。
            minRatio: 0.8
            // 只有压缩率小于这个值的资源才会被处理。默认值是 0.8。
        })
    )
}

添还需要在nginx配置gzip_static on;,这样nginx 会优先匹配 gzip 文件来返回,如果没有就寻找相应资源进行 gzip 压缩再返回

优点:减少了服务器压缩文件的压力

缺点:打包时间变长

2》代码压缩

对于js:terser-webpack-plugin

  optimization: {
    minimize: true,
	,
  },
    minimizer: [
      new TerserPlugin({
        parallel: true, //开启并行压缩,可以加快构建速度
      }),
    ],

对于css: css-minimizer-webpack-plugin

  optimization: {
    minimizer: [new cssMinimizerPlugin({
           parallel: true
       }
      )],
  },
3》分包优化

webpack5中splitChunks可以进行分包优化

  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        echarts: {
          name: 'chunk-echarts',
          priority: 20,
          test: /[\\/]node_modules[\\/]_?echarts(.*)/,
        },
      },
    },
  },
4》通过cdn方式引入外部库

**externals **引入外部库, 无需webpack打包处理

  externals: {
    echarts: 'echarts',
  },

在html中引入

    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>

组件中无需引入,可以直接使用echarts

   const myChart = echarts.init(dom)
5》source-map

测试环境:

  devtool: 'eval-cheap-module-source-map'

生产环境:

  devtool: false 
  devtool: "nosources-source-map"

不同source-map的选择

false不会有sourcemap

eval- :生成source-map,不会生成额外的 .map文件,而是在eval 函数内附加 source map推荐在开发环境中使用

inline-:不会生成 .map文件,但是会将SourceMap内联到原始文件中

hidden- : source map 但是不会将其关联

nosources- sourcemap 中不带源码, 但会有准确的错误行列信息, 避免源码泄露

cheap- 忽略”列“信息,source map 只有“行”映射,可以加快打包速度

对于开发环境,通常希望更快速的 source map,需要添加到 bundle 中以增加体积为代价,但是对于生产环境,则希望更精准的 source map,需要从 bundle 中分离并独立存在

6》tree-shaking

在webpack5之前,如果一个文件中引用多个函数,却使用一个函数,那么多个函数都会被打包

但是webpack5能解析出依赖图谱,去除最终没有被使用的代码,生产模式下会进行 tree-shaking

复制代码

webpack5是有自动的tree-shaking

7》路由懒加载

路由懒加载可以将不同的路由对应的内容打包到不同文件中,而且用户访问对应路由时才会加载相应的组件(静态导入时,所有路由组件都会被打包到同一个文件中)

为什么按需引入没有是打包体积减小反而更大?

在使用ant-design-vue的时候,发现按需引入组件,打包体积反而更大了

原因是一些公用的东西,依赖等,如果是一起打包,就只要引用打包一次,按需引入则每个组件需要引用一份,就会打包进去一次

对于只用了很少组件的第三方库,比如本测试的echarts,按需引入会有很明显的优化效果,但是如果使用了很多,按需引入不一定更好


http://www.kler.cn/a/157423.html

相关文章:

  • 设计模式の享元模板代理模式
  • Tomcat部署war包项目解决404问题
  • 彻底认识和理解探索分布式网络编程中的SSL安全通信机制
  • 有监督学习 vs 无监督学习:机器学习的两大支柱
  • cenos如何升级git到2以上版本
  • Java并发编程框架之综合案例——在线聊天室(二)
  • ARM与大模型,狭路相逢
  • 探索人工智能领域——每日20个名词详解【day6】
  • 关于近期互联网行业收缩的一些看法
  • 关于rocketMQ踩坑的那些事
  • 【hacker送书第8期】Java从入门到精通(第7版)
  • Unity Meta Quest 一体机开发(八):【手势追踪】实现 Hand Grab 扔物体功能
  • Kotlin学习之04
  • 时间序列预测实战(二十三)进阶版LSTM多元和单元预测(课程设计毕业设计首选)
  • 【初阶解法-数据结构】包含min函数的栈(代码+图示)
  • 熬夜会秃头——beta冲刺Day7
  • 【开源】基于Vue.js的河南软件客服系统
  • 【Node-RED】http response收发实现
  • Shell数组函数:数组(一)
  • 如何制作教育培训小程序
  • 数字孪生是什么,是干什么用的?
  • 01 高等数学.武忠祥.0基础
  • 考虑光伏发电的配电网重构策略研究
  • 一次elasticsearch 查询瞬间超时案例分析
  • GEE:使用Roberts算子卷积核进行图像卷积操作
  • 【C语言】深入理解C语言中的数学运算和类型转换