vue3+vite+ts项目打包优化【前端记录】

视图分析工具rollup-plugin-visualizer

在项目中使用 rollup-plugin-visualizer 插件可以生成可视化的代码分析报告,看看哪些模块占用了空间,帮助我们更好地了解构建过程中的文件大小、依赖关系等信息。

  1. 首先安装了 rollup-plugin-visualizer 插件。可以使用 npm 或者 yarn 进行安装:
cmd 复制代码
yarn add rollup-plugin-visualizer -D
npm i rollup-plugin-visualizer -D
  1. vite.config.ts中引入 rollup-plugin-visualizer 插件,并将其添加到插件列表中。
javascript 复制代码
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
  plugins: [
  vue(), 
  visualizer({
    open: true, //在默认用户代理中打开生成的文件
    gzipSize: true, // 收集 gzip 大小并将其显示
    brotliSize: true, // 收集 brotli 大小并将其显示
    filename: "stats.html", // 分析图生成的文件名
  }),
})
  1. 运行命令打包,生成分析图。 执行npm run build命令后等待片刻,生成分析视图,视图会自动跳出来,并保存在项目根目录下,文件名就是刚刚参数filename的名字(stats.html)
cmd 复制代码
npm run build
  1. 在生成的打包文件所在目录下,会生成一个名为 stats.html 的文件,这就是生成的可视化报告。

    打开 stats.html 文件,你将看到一个交互式的可视化图表,显示了打包文件中各个模块的大小、依赖关系等信息。你可以通过这个图表来识别哪些模块占用了较大的空间,从而进行代码优化。

视图分析中方块越大,表示该文件占用的空间越大,对于网络带宽和访问速度的要求就越高。如果一个网站中包含大量的大文件,那么用户在访问该网站时需要下载更多的数据,这会导致网站加载速度变慢,用户体验变差。

配置打包文件分类输出

指定不同类型文件的输出格式

将js,css,图片等资源分别打包到对应的文件夹下,这种方式适合小型项目或者需要快速搭建原型的项目。Vite的默认配置能够很好地满足这些项目的需求,我们就不需要花费太多时间在打包配置上。

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

js最小拆包

通过最小化拆分包,我们可以将项目代码划分为多个模块或块,每个模块只包含当前页面或功能所需的代码。当用户访问特定页面时,只需加载该页面所需的模块,而无需加载整个项目代码。这可以减少初始加载时间和资源消耗,适合较大型的项目或者对打包配置有特殊需求的项目。

js 复制代码
export default defineConfig({
  // 其他配置项...
   build: {
    rollupOptions: {
      output: {
        // 最小化拆分包
        manualChunks(id) {
          if (id.includes("node_modules")) {
            // 通过拆分包的方式将所有来自node_modules的模块打包到单独的chunk中
            return id
              .toString()
              .split("node_modules/")[1]
              .split("/")[0]
              .toString();
          }
        },
        // 设置chunk的文件名格式
        chunkFileNames: (chunkInfo) => {
          const facadeModuleId = chunkInfo.facadeModuleId
            ? chunkInfo.facadeModuleId.split("/")
            : [];
          const fileName1 =
            facadeModuleId[facadeModuleId.length - 2] || "[name]";
          // 根据chunk的facadeModuleId(入口模块的相对路径)生成chunk的文件名
          return `js/${fileName1}/[name].[hash].js`;
        },
        // 设置入口文件的文件名格式
        entryFileNames: "js/[name].[hash].js",
        // 设置静态资源文件的文件名格式
        assetFileNames: "[ext]/[name].[hash:4].[ext]",
      },
    },
  },
});

剔除console和debugger

  1. vite 4.X 版本已经不集成 terser,需要自行下载。
cmd 复制代码
yarn add terser -D
npm i terser -D
  1. vite.config.ts中进行配置
javascript 复制代码
import { defineConfig } from "vite";  
export default defineConfig({  
    build: {  
        minify: 'terser', // 启用 terser 压缩  
        terserOptions: {  
            compress: {  
                pure_funcs: ['console.log'], // 只删除 console.log 
                //drop_console: true, // 删除所有 console
                drop_debugger: true, // 删除 debugger  
            }  
        }  
    }  
})  

图片资源压缩

  1. 安装vite-plugin-imagemin插件,由于这个插件在国内不好安装,所以需要先改配置
  • 使用yarn安装需要在package.json添加以下配置
package.json 复制代码
"resolutions": {
    "bin-wrapper": "npm:bin-wrapper-china"
}
  • 使用npm,在电脑host文件加上以下配置
host 复制代码
199.232.4.133 raw.githubusercontent.com
  • 安装插件
cmd 复制代码
yarn add vite-plugin-imagemin -D
npm i vite-plugin-imagemin -D
  1. vite.config.ts中进行配置
javascript 复制代码
import viteImagemin from 'vite-plugin-imagemin';
plugin: [
  viteImagemin({
    gifsicle: {
      optimizationLevel: 7, // 设置GIF图片的优化等级为7
      interlaced: false // 不启用交错扫描
    },
    optipng: {
      optimizationLevel: 7 // 设置PNG图片的优化等级为7
    },
    mozjpeg: {
      quality: 20 // 设置JPEG图片的质量为20
    },
    pngquant: {
      quality: [0.8, 0.9], // 设置PNG图片的质量范围为0.8到0.9之间
      speed: 4 // 设置PNG图片的优化速度为4
    },
    svgo: {
      plugins: [
        {
          name: 'removeViewBox' // 启用移除SVG视图框的插件
        },
        {
          name: 'removeEmptyAttrs',
          active: false // 不启用移除空属性的插件
        }
      ]
    }
  })
]
  1. 压缩之后的图片小了很多

按需引入第三方库

对于一些较大的第三方库,如 Element UIAnt Design,可以考虑按需引入组件或样式,而不是全部引入。按需引入组件或样式可以参考这些第三方库的官方文档,在里面有介绍如何按需引入组件或样式。

路由懒加载

路由懒加载的实现方式通常是使用动态导入(Dynamic Import)语法,比如在 Vue 项目中使用 import() 来导入需要懒加载的组件。当用户访问到对应的路由时,该组件才会被异步加载,实现了按需加载的效果。

  • 示例代码
js 复制代码
const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue')
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  }
]

使用 Tree Shaking

  1. 确保你的项目使用了ES模块作为模块系统,这样Tree Shaking才能正常工作。在Vite中,默认就是使用ES模块。

  2. 确保你的代码按照ES模块的规范进行导出和导入。例如,使用export关键字导出模块,使用import关键字导入模块。

  3. 确保你的代码是静态的,即在编译时可确定模块的导入和导出关系。这样Tree Shaking才能在编译时确定哪些代码是不需要的,从而将其删除。

  4. 在项目的tsconfig.json文件中的compilerOptions中添加以下代码

ts 复制代码
{
  "compilerOptions": {
    //······
    "removeComments": true, // 是否移除 TypeScript 代码中的注释
    "noEmitHelpers": true, // 是否禁止生成 TypeScript 帮助函数
    "downlevelIteration": true, // 是否将 for...of 循环编译为适用于旧版 JavaScript 的代码
    "importHelpers": true // 是否使用模块化方式引入帮助函数
    //······
  }
}
  1. 确保你的代码库中没有副作用的代码,即没有在导入模块时执行任何副作用操作(如修改全局变量等)。这是因为Tree Shaking将会删除没有被使用到的代码,包括副作用代码。

第三方库CDN引入

在项目中可根据需要引入第三方库CDN,使用CDN引入第三方库可以提高项目的性能和开发效率,减少项目的体积,同时也可以减轻服务器的负担,提高用户体验。

  1. 安装插件
cmd 复制代码
npm install vite-plugin-cdn-import -D
yarn add vite-plugin-cdn-import -D
  1. vite.config.ts中进行配置
js 复制代码
import { defineConfig } from 'vite';
import compression from 'vite-plugin-compression';
export default defineConfig({
  // 其他配置项...
  plugins: [
    // 其他插件...
    // 第三方库CDN引入
    importToCDN({
      prodUrl: "https://unpkg.com/{name}@{path}",
      modules: [
        autoComplete('vue'),
        autoComplete('axios'),
     // {
     //   name: "vue",
     //   var: "Vue",
     //   path: "3.3.4",
     //  },
        {
          name: "vue-demi", // vue版本选好 不然会报错
          var: "VueDemi",
          path: "0.14.5",
        },
        {
          name: "vue-router",
          var: "VueRouter",
          path: "4.2.2",
        },
        {
          name: "element-plus",
          var: "ElementPlus",
          path: "2.3.6",
          css: "2.3.6/dist/index.css",
        },
        {
          name: "@element-plus/icons-vue",
          var: "ElementPlusIconsVue", // 根据main.js中定义的来
          path: "2.1.0",
        },
        {
          name: "pinia",
          var: "Pinia",
          path: "2.1.3",
        },
      ],
    }),
  ],
});

使用 gzip 压缩

gzip压缩是一种常用的数据压缩算法,它可以减小文件的大小,从而减少文件的传输时间和占用空间。gzip压缩算法基于DEFLATE算法,使用了哈夫曼编码和LZ77算法来实现高效的数据压缩。

当使用gzip压缩文件时,文件会被转换为一种经过压缩和编码的格式。这种格式可以通过减少冗余数据和使用更紧凑的编码方式来降低文件的大小。压缩后的文件通常以.gz为扩展名。

  1. 安装插件
cmd 复制代码
yarn add vite-plugin-compression -D
npm i vite-plugin-compression -D
  1. vite.config.ts中进行配置
js 复制代码
import { defineConfig } from 'vite';
import compression from 'vite-plugin-compression';
export default defineConfig({
  // 其他配置项...
  plugins: [
    // 其他插件...
    compression({
      algorithm: "gzip", // 指定压缩算法为gzip,[ 'gzip' , 'brotliCompress' ,'deflate' , 'deflateRaw']
      ext: ".gz", // 指定压缩后的文件扩展名为.gz
      threshold: 10240, // 仅对文件大小大于threshold的文件进行压缩,默认为10KB
      deleteOriginFile: false, // 是否删除原始文件,默认为false
      filter: /\.(js|css|json|html|ico|svg)(\?.*)?$/i, // 匹配要压缩的文件的正则表达式,默认为匹配.js、.css、.json、.html、.ico和.svg文件
      compressionOptions: { level: 9 }, // 指定gzip压缩级别,默认为9(最高级别)
      verbose: true, //是否在控制台输出压缩结果
      disable: false, //是否禁用插件
    }),
  ],
});
  1. 压缩后的文件小了很多

小结

这是我第一次对项目进行打包优化的一次记录,本人水平有限,如有错误欢迎在评论区指正,一起讨论!(๑•̀ㅂ•́)و✧

相关推荐
正小安1 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch3 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光3 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   3 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   3 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web3 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常3 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
韩楚风4 小时前
【linux 多进程并发】linux进程状态与生命周期各阶段转换,进程状态查看分析,助力高性能优化
linux·服务器·性能优化·架构·gnu
莹雨潇潇4 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr4 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui