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;
}
属性 说明
gzip on/off,是否开启gzip压缩
gzip_types 压缩哪些文件类型
gzip_min_length eg: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,按需引入会有很明显的优化效果,但是如果使用了很多,按需引入不一定更好

相关推荐
不吃鱼的羊15 分钟前
DaVinci配置NVM模块
前端·javascript·网络
excel25 分钟前
为什么需要构建工具(Webpack / Vite 的本质)
前端
lang2015092825 分钟前
Java SAX 流式解析全解:从原理到 EasyExcel 实战
java·前端·javascript
Rain50933 分钟前
2.4. PostgreSQL 数据库连接与实战指南
前端·数据库·人工智能·后端·postgresql·数据分析
console.log('npc')33 分钟前
Codex 桌面端接入 Headroom 压缩代理完整教程
前端·vscode
独泪了无痕1 小时前
Vue集成uuid生成唯一标识实践指南
前端·vue.js
yuanyxh9 小时前
Mac 软件推荐
前端·javascript·程序员
万少9 小时前
AtomCode开发微信小程序《谁去呀》 全流程
前端·javascript·后端
某人辛木9 小时前
Web自动化测试
前端·python·pycharm·pytest
Kagol10 小时前
Superpowers GSD gstack AgentSkills深度测评
前端·人工智能