基于Vite构建的Vue3+Ts项目打包优化全过程

前置工具

打包体积分析器:rollup-plugin-visualizer是一个打包体积分析插件,对应webpack中的webpack-bundle-analyzer。配置好后运行构建命令会生成一个stats.html。

npm i rollup-plugin-visualizer -D
Pnpm add rollup-plugin-visualizer -D

在vite.config.js里面配置

import { visualizer } from 'rollup-plugin-visualizer'
plugins: [
    visualizer({open: true})
]

打包完成后会生成并自动打开一个HTML文件,类似下图:
基于Vite构建的Vue3+Ts项目打包优化全过程_第1张图片

配置打包文件分类输出

将js,css这些资源目录分别打包到对应的文件夹下

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

js最小拆分包

  • 配置vite.config 的 output 属性
  • 让打开那个页面,加载那个页面的js ,让之间的关联足够小
  • 让打开那个页面,加载那个页面的js ,让之间的关联足够小
  output: {
    // 最小化拆分包
    manualChunks(id) {
      if (id.includes('node_modules')) {
        return id.toString().split('node_modules/')[1].split('/')[0].toString();
      }
    }
  },

代码压缩+剔除console+debugger

**esbuild **or **terser,**默认启动的是 esbuild, esbuild,比 terser 快 20-40倍,压缩率只差 1%-2%。

esbuild:

只删除 console.logdebugger

import {defineConfig} from "vite";
export default defineConfig({
    esbuild:{
        pure: ['console.log'], // 删除 console.log
        drop: ['debugger'], // 删除 debugger
    }
})

删除所有的console语句和debugger,包括console.log、console.warn、console.error等。

import {defineConfig} from "vite";
export default defineConfig({
    esbuild:{
        drop: ['console,'debugger'], // 删除 所有的console 和 debugger
    }
})

terser:

vite 4.X 版本已经不集成 terser,需要自行下载。

Pnpm add terser -D
npm i terser -D

只删除 console.log 和** debugger**

import { defineConfig } from "vite";  
export default defineConfig({  
    build: {  
        minify: 'terser', // 启用 terser 压缩  
        terserOptions: {  
            compress: {  
                pure_funcs: ['console.log'], // 只删除 console.log  
                drop_debugger: true, // 删除 debugger  
            }  
        }  
    }  
})  

删除所有的console语句和debugger,包括console.log、console.warn、console.error等。

import {defineConfig} from "vite";
export default defineConfig({
    build: {
        minify: 'terser', // 启用 terser 压缩
        terserOptions: {
            compress: {
                drop_console: true, // 删除所有 console
                drop_debugger: true,// 删除 debugger
            }
        }
    }
})

文件压缩

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

当请求静态资源时,服务端发现请求资源为gzip的格式时,应该设置响应头 content-encoding: gzip 。因为浏览器解压也需要时间,所以代码体积不是很大的话不建议使用 gzip 压缩。

图片资源压缩:

安装插件

npm i vite-plugin-imagemin -D
pnpm add vite-plugin-imagemin -D

在vite.config.js里面配置

import viteImagemin from 'vite-plugin-imagemin'
plugin: [
    viteImagemin({
      gifsicle: {
        optimizationLevel: 7,
        interlaced: false
      },
      optipng: {
        optimizationLevel: 7
      },
      mozjpeg: {
        quality: 20
      },
      pngquant: {
        quality: [0.8, 0.9],
        speed: 4
      },
      svgo: {
        plugins: [
          {
            name: 'removeViewBox'
          },
          {
            name: 'removeEmptyAttrs',
            active: false
          }
        ]
      }
    })
]

压缩前的图片资源大小:
基于Vite构建的Vue3+Ts项目打包优化全过程_第2张图片
压缩后的图片资源,整体瘦身60%以上
基于Vite构建的Vue3+Ts项目打包优化全过程_第3张图片

按需加载优化一些包的体积

比如loadsh,项目中只用到了{cloneDeep 、throttle、debouce}这个几个函数,但是由于lodash是common.js版本不支持按需引入,500多k全部打包进来了。
基于Vite构建的Vue3+Ts项目打包优化全过程_第4张图片
lodash-es 是 lodash 的 es modules 版本 ,是着具备 ES6 模块化的版本,支持按需导入,使用loadsh-es代替lodash,按需引入,减少打包体积。

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

CDN加速

打包构建时,不打包配置指定的外部模块,减少应用打包出来的包体积,使用CDN方式来引用(不建议使用第三方cdn,原因见下文分析,这里做学习讨论使用)

插件安装

pnpm add rollup-plugin-external-globals -D

vite.config.ts里面配置


import externalGlobals from 'rollup-plugin-external-globals';

const globals = externalGlobals({
  moment: 'moment',
  'video.js': 'videojs',
  jspdf: 'jspdf',
  xlsx: 'XLSX',
});

export default defineConfig({
    build: {
        rollupOptions: {
            external: ['moment', 'video.js', 'jspdf','xlsx'],
            plugins: [globals],
        }
    }
});

在 index.html 模版中引入对应库的CDN。

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

https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js
https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
    <script src="https://.../moment.min.js"></script>
    <script src="https://.../xlsx.full.min.js"></script>
    <script src="https://.../jspdf.polyfills.umd.js"></script>
    <script src="https://.../jspdf.umd.min.js"></script>
    <script src="https://.../video.min.js"></script>

优化效果,4.14M->2.85M

基于Vite构建的Vue3+Ts项目打包优化全过程_第5张图片
基于Vite构建的Vue3+Ts项目打包优化全过程_第6张图片

采用CDN引入的弊端:

  1. 可靠性:使用CDN引入外部模块意味着依赖于第三方服务商的可用性和稳定性。如果CDN服务商发生故障或者网络问题,可能会导致外部模块无法加载,影响网站的正常运行。
  2. 安全性:使用CDN引入外部模块需要信任第三方服务商,因为模块实际上是从服务商的服务器上加载的。如果服务商被黑客攻击或者恶意篡改了模块的内容,可能会导致安全问题。
  3. 性能:CDN服务通常会根据用户的地理位置选择最近的节点进行内容分发,这样可以减少网络延迟和提高访问速度。但是如果用户所在地区的CDN节点发生故障或者网络拥堵,可能会导致加载速度变慢甚至加载失败。
  4. 版本控制:使用CDN引入外部模块可能会导致版本控制的问题。如果模块的版本发生变化,CDN服务商可能会立即更新节点上的内容,这样可能会导致网站出现兼容性问题或者功能异常。

题外话:SEO优化,vite实现预渲染

yarn add vite-plugin-prerender -D
npm i vite-plugin-prerender -D
pnpm add vite-plugin-prerender -D

在vite.config.js中使用

import vitePrerender from 'vite-plugin-prerender'
import path from 'path'

export default () => {
  return {
    plugins: [
      vitePrerender({
        // Required - The path to the vite-outputted app to prerender.
        staticDir: path.join(__dirname, 'dist'),
        // Required - Routes to render.
        routes: ['/', '/chat', '/design'],
      }),
    ],
  }
}

打包完成后,会根据配置的路由地址,在dist文件中生成对应的html文件。
基于Vite构建的Vue3+Ts项目打包优化全过程_第7张图片

你可能感兴趣的:(性能优化,vue)