分享基于vite对vue3项目打包优化经验(持续更新)

性能工具


当项目打包完如何分析各个包的打包体积?

可以安装 **rollup-plugin-visualizer**插件(vite插件),它是一个打包体积分析插件,可以看到打包后的所有文件大小,可以用于判断配置vite优化前后包体积大小的变化

npm i rollup-plugin-visualizer -D
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
  plugins: [
     // 打包体积分析
    visualizer({
      open: true,
      filename: 'visualizer.html' //分析图生成的文件名
    }),
  ],
})

打包完成会生成一个html文件,就可以看到各个包的体积大小了


vite打包优化过程


实现自动按需引入


利用`unplugin-vue-components`插件实现组件自动按需导入,
利用`unplugin-auto-import`插件实现自动按需引入

具体配置

npm install -D unplugin-vue-components unplugin-auto-import
// 按需自动引入导入element plus。
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'


我项目是用在按需自动引入导入element plus库

export default defineConfig({
  plugins: [
    // 按需导入element plus组件
    AutoImport({
      resolvers: [ElementPlusResolver()]
    }),
    // 按需导入element plus 自定义主题。
    Components({
      resolvers: [ElementPlusResolver({ importStyle: 'sass' })]
    }),
  ],
})

配置打包文件分类输出

build: {
    rollupOptions: {
      output: {
        chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称
        entryFileNames: 'js/[name]-[hash].js', // 包的入口文件名称
        assetFileNames: '[ext]/[name]-[hash].[ext]', // 资源文件像 字体,图片等
      }
    }
}

最小化拆分包

 将需要分离的包单独的打包出来

  output: {
    // 最小化拆分包
    manualChunks(id) {
      if (id.includes('node_modules')) {
        return id.toString().split('node_modules/')[1].split('/')[0].toString();
      }
    }
  },


开启图片压缩

// 图片压缩
import viteImagemin from 'vite-plugin-imagemin'
export default defineConfig({
  plugins: [
     // 图片资源压缩
    viteImagemin({
      gifsicle: {
        // gif图片压缩
        optimizationLevel: 3, // 选择1到3之间的优化级别
        interlaced: false // 隔行扫描gif进行渐进式渲染
      },
      optipng: { // png
        optimizationLevel: 7 // 选择0到7之间的优化级别
      },
      mozjpeg: {// jpeg
        quality: 20 // 压缩质量,范围从0(最差)到100(最佳)。
      },
      pngquant: {// png
        quality: [0.8, 0.9], // Min和max是介于0(最差)到1(最佳)之间的数字,类似于JPEG。达到或超过最高质量所需的最少量的颜色。如果转换导致质量低于最低质量,图像将不会被保存。
        speed: 4 // 压缩速度,1(强力)到11(最快)
      },
      svgo: {
        plugins: [
          // svg压缩
          {
            name: 'removeViewBox'
          },
          {
            name: 'removeEmptyAttrs',
            active: false
          }
        ]
      }
    }),
  ],
})


开启压缩后图片体积大小减少60%以上


文件压缩

问:开启Gzip压缩能压缩哪些类型的文件?

1、对文本进行压缩

支持对文本进行压缩,这里的文本包括 HTML、CSS、JS文件,都会进行不一定程度的压缩。

2、不支持对非文本类型压缩

像咱们常见的图片(JPEG、PNG、GIF)都属于非文本类型,gzip 都不支持压缩哦。

//Gzip文件压缩
import viteCompression from 'vite-plugin-compression'
export default defineConfig({
  plugins: [
     //开启Gzip压缩
    viteCompression({
      verbose: true, // 是否在控制台中输出压缩结果
      disable: false,
      threshold: 1024, // 如果体积大于阈值,将被压缩,单位为b,体积过小时请不要压缩,以免适得其反
      algorithm: 'gzip', // 压缩算法,可选['gzip',' brotliccompress ','deflate ','deflateRaw']
      ext: '.gz',
      deleteOriginFile: true // 源文件压缩后是否删除(我为了看压缩后的效果,先选择了true)
    })
  ],
})


开启CDN加速

pnpm add rollup-plugin-external-globals -D

const globals = externalGlobals({
  lodash: 'lodash',
  jspdf: 'jspdf',
  html2canvas: 'html2canvas'
})

export default defineConfig({
  build: {
    rollupOptions: {
      //打包时不引入外部模块,使用cdn引入
      external: ['lodash', 'jspdf', 'html2canvas'],
      plugins: [globals]
    },
  }
})


在index.html文件的head标签内引入对应库的CDN


  

具体的CDN链接根据自己需要去官网或是CDN网站查询,cdn网站:cdnjs.com/
    


terser 压缩和去除console+debugger

npm i terser -D
export default defineConfig({
   build: {
    minify: 'terser',
    // 清除所有console和debugger
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true
      }
    }
  }
})

最后,项目打包后的体积大小从4.52MB变小为2.86MB

优化前

优化后


  
  


其它还未应用的优化


预渲染


进行SEO优化

npm i vite-plugin-prerender -D
// 预渲染
import vitePrerender from 'vite-plugin-prerender'
export default defineConfig({
  plugins: [
    // 预渲染
    vitePrerender({
      staticDir: path.join(__dirname, 'dist'),
      routes: ['/', '/design', '/index']
    }),
  ],
})


打包完成后,会根据配置的路由地址,在dist文件中生成对应的index.html文件


SVG图标优化


svg组件封装优化是我在其它项目使用的优化


在开发项目的时候会用到svg矢量图,而且我们使用SVG以后,页面上加载的不再是图片资源,
这对页面性能来说是个很大的提升,而且SVG文件比img体积大小要小很多

安装SVG依赖插件

pnpm install vite-plugin-svg-icons -D

在`vite.config.ts`中配置插件

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
export default () => {
  return {
    plugins: [
      createSvgIconsPlugin({
        // Specify the icon folder to be cached
        iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
        // Specify symbolId format
        symbolId: 'icon-[dir]-[name]',
      }),
    ],
  }
}


入口文件导入

import 'virtual:svg-icons-register'

svg组件封装

<template>
  <div>
    <svg :style="{ width: width, height: height }">
      <use :xlink:href="prefix + name" :fill="color"></use>
    </svg>
  </div>
</template>

<script setup lang="ts">
defineProps({
  //xlink:href属性值的前缀
  prefix: {
    type: String,
    default: '#icon-'
  },
  //svg矢量图的名字
  name: String,
  //svg图标的颜色
  color: {
    type: String,
    default: ""
  },
  //svg宽度
  width: {
    type: String,
    default: '16px'
  },
  //svg高度
  height: {
    type: String,
    default: '16px'
  }

})
</script>
<style scoped></style>


按需加载第三方包的体积

比如loadsh,项目中可能只用到了cloneDeep 、throttle这几个函数,但是由于lodash是common.js版本不支持按需引入,整个包都会被打包进来,影响性能

lodash-es 是 lodash 的 es modules 版本 ,具备 ES6 模块化的版本,可以按需导入,**使用loadsh-es代替lodash,按需引入,减少打包体积**

import _ from 'lodash-es'; // 将会把整个lodash的库引入到项目
import { cloneDeep } from 'lodash-es'; // 将只会把cloneDeep引入到项目

自动重启 vite 服务

使用 `vite-plugin-restart` 插件,监听 `vite.config.js` 或 `.env.development` 等配置文件修改直接生效,不需要反复重启 Vite

npm i vite-plugin-restart -D
import ViteRestart from 'vite-plugin-restart'
export default {
  plugins: [
    ViteRestart({
      restart: [
        'my.config.[jt]s'
      ]
    })
  ],
}

  • 30
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值