Vite 打包性能优化

news2025/2/27 21:08:58

Vite 打包性能优化

    • 开始一个 Vite + ts 项目
      • 分包策略
      • gzip 压缩
      • cdn 加速

开始一个 Vite + ts 项目

这里我们开始了一个 Vite + ts 的项目,其中关于 ts 的配置直接看内容注释即可

npm init -y
npm i vite -D
npm vite-plugin-checker -D #用来强制提示ts报错
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <script src="./src/main.ts" type="module"></script>  
</body>
</html>
// tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true, // 跳过node_modules中的ts检查
    "module": "ESNext", // 使用最新的js语法
    "moduleResolution": "node", // 导入第三方包时候会使用commonjs规范解析
    "lib": ["ES2017", "DOM"], // ts默认项目环境不在es6,所以使用es方法会报错,因此这里指定一下es环境
  }
}
// package.json
"scripts": {
  "dev": "vite",
  "build": "tsc --noEmit && vite build"
},

其中 tsc --noEmit 是根据官方提示,在ts报错时不给出打包结果

// vite.config.ts
import { defineConfig } from 'vite'
import VitePluginChecker from 'vite-plugin-checker'

export default defineConfig({
  build: {
    minify: false, // 打包结果取消minify,方便我们看打包后结果对比
  },
  plugins: [
    VitePluginChecker({
      typescript: true, // 当typescript语法错误时浏览器给出错误提示弹窗,强制开发者修改ts错误
    })
  ]
})
// src/main.ts
// 内容

分包策略

npm i lodash
// src/main.ts
import { forEach } from 'lodash'

const mainArr = []

forEach(mainArr, ele => {
  console.log('ele', ele)
})

执行打包命令:

npm run build

结果:

在这里插入图片描述

题外话:npx vite preview 可以预览打包后的效果。

项目场景:因为浏览器的缓存策略,当请求的文件名不变时,会直接从缓存中获取文件,所以只要每次 main.ts 中内容发生了变化,打包后的文件名中的 hash 值都会不一样。也就是说,当项目业务代码发生变化,例如 main.ts 中循环体内的内容发生了变化时,打包后的文件名就发生了变化,浏览器就会重新请求文件。但是这里的问题是,每次打包后的内容大部分都是 lodash 库的内容,它的内容是不会变化的(node_modules 中的代码都是不会变化的),我们只是更改了业务代码而已,会导致每次浏览器请求的文件都很大,很大的网络传输损耗。

分包策略就是为了解决这个问题,它会将一些不常规更新变化的文件进行单独打包处理。

// vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    minify: false, // 打包结果是否minify
    rollupOptions: { // vite打包是通过rollup来打包的
      output: {
        manualChunks: (id: string) => {
          // 可以在这里打印看一下id的值,这里做个简单处理将node_modules中的包打包为vendor文件
          if(id.indexOf('node_modules') > -1) {
            return 'vendor'
          }
        }
      }
    }
  },
  plugins: [...]
})

执行打包命令

npm run build

在这里插入图片描述

此时,如果去修改 main.ts 中循环体内容,重新打包后,vendor 文件的 hash 值不会变化,变化的只有 index 文件的,而这个文件比一开始的包小了不是一点点,这也就意味着,浏览器会从缓存中获取 vendor 文件,节省了很大的网络性能。

gzip 压缩

上面打包后的终端提示可以拿过来再看一下

在这里插入图片描述

每个文件打包后的大小都有标识,后面一个 gzip 表示经过 gzip 压缩可以将这个文件缩小到 xxx 这个大小,这里我们来实践一下:

npm i vite-plugin-compression -D
// vite.config.ts
import { defineConfig } from 'vite'
import VitePluginCompression from 'vite-plugin-compression'

export default defineConfig({
  build: {
    ...
  },
  plugins: [
    ...
    VitePluginCompression()
  ]
})

执行打包操作:

npm run build

在这里插入图片描述

和上面未使用 gzip 打包给出的大小提示一样,打包的结果是 .gz 文件。此时,需要跟后端商量,当请求文件是 .gz 文件时,需要设置响应头为 content-encoding: gzip(告诉浏览器这个文件是 gzip 压缩过的) ,浏览器收到响应结果后发现响应头中的这个设置项就会立即解压得到原来的 .js 文件。

当然,这样会使得浏览器需要承担一定的解压时间,所以体积不是很大的时候,不要用 gzip 压缩,免得适得其反。

cdn 加速

分发策略里我们将依赖单独打成一个稳定的包,现在是另外一个场景:比如国内访问一些未被封的国外网站(例如 github、newsela 等)网站时,因为服务器在国外,所以浏览器打开这些网站时请求时间一般都会比较久。即使你分包了,但是如果这个包体积很大,访问时间还是会很长,因为是从国内访问国外了。如果我们将其中一些依赖包经过 cdn 的方式访问,例如 Vue vue-router 这些包通过 cnd 的方式访问,那么这些包就会直接通过 cdn 地址的方式加载,而不是在我们的服务器上去请求,这样我们的项目包就会更小,页面响应就会更快。

// vite.config.js
import { defineConfig } from 'vite'
import ViteCDNPlugin from 'vite-plugin-cdn-import'

export default defineConfig({
  plugins: [
    ViteCDNPlugin({
      modules: [{
        name: 'lodash', // 包名
        var: '_', // 对应cdn包导出的变量,如jQuery导出的是$
        path: 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js'
      }]
    })
  ]
})

执行打包命令后:

npm run build

在这里插入图片描述

没有分包,lodash 也不会被打入包中,打包后的 index.html 会自动插入 cdn 方式加载 lodash 包,项目打包后的体积也明显小了很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/407720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

反射时竟然NoSuchMethodException了!看这篇超详细的解决方案吧

前几天九哥在讲Servlet时&#xff0c;为了灵活地使用同一个Servlet来处理对同一张表的业务操作请求&#xff0c;我给学生讲解了BaseServlet工具类的封装&#xff0c;基本实现思路有如下几个步骤。 一. 反射封装BaseServlet工具类 使用反射封装BaseServlet工具类&#xff0c;无…

uview常用组件案例操作及详解(一) 选择器 picker

uview常用组件案例操作及详解&#xff08;一&#xff09; 选择器 picker 1.图片示例 2.使用方法 *为简便代码不提供样式 <view><view><text>行业性质</text><text>*</text></view><view><text v-if"!text.industry…

echarts中的legend属性

legend: {orient: "vertical",right: "0%",top: "15%",icon: "circle", //小圆点itemWidth: 8,itemHeight: 8,itemGap: 15, //间隔formatter: function (params) {let tip1 "";let tip "";let le params.leng…

【uni-app】swiper的使用

最近在学习小程序的开发&#xff0c;其中有用到swiper&#xff0c;在这里记录一下我的学习历程 有一些人&#xff0c;他刚开始并不会开发小程序&#xff0c;但是在任务面前&#xff0c;没有什么是不可以学的… 刚开始接触到swiper的时候&#xff0c;是在uni-app的官方文档里&am…

Vue中的Pinia状态管理工具 | 一篇文章教会你全部使用细节

文章目录Pinia状态管理Pinia和Vuex的对比Pinia基本使用&#x1f364;创建Pinia&#x1f364;创建StorePinia核心概念State&#x1f35f;state基本使用&#x1f35f;state其他操作Pinia核心Getters&#x1f355;getters基本使用&#x1f355;getters其他操作Pinia核心Actions&am…

React -- useState 的使用及注意事项

一、基本使用 useState是 react 提供的一个定义响应式变量的 hook 函数&#xff0c;基本语法如下&#xff1a; const [count, setCount] useState(initialCount)它返回一个状态和一个修改状态的方法&#xff0c;状态需要通过这个方法来进行修改&#xff1b;initialCount 是我…

Vue3+Vite实现动态路由

项目基本目录 1.首先定义初始默认的路由routes(router.js文件),vue文件使用import引入可以按需加载 import {createRouter,createWebHashHistory } from "vue-router";import store from ../store/index.jsconst routes [{path: "/login",component: () …

jsjiami.com V6版本,js解密的方法。

我们在爬内容&#xff0c;抓取页面的时候&#xff0c;总会遇到sojson v5&#xff0c;jsjiami.com的v6加密。 jsjiami v6 &#xff1a; JS加密,JS不可逆加密,JS混淆,JS混淆加密,JS压缩加密 - [JavaScript加密] 我看了下这个js完全有效。废话不多说。直接上代码。 (function (…

vue中深度选择器

scoped的作用 scoped 可以使当前的样式只在自己当前的组件内起作用。为了防止在一个组件内引入了子组件&#xff0c;而子组件没有加scoped。这个时候如果父子组件有相同的类名&#xff0c;就会产生样式的影响。 原理: 加了scoped就相当于给当前组件所有的标签添加一个【data-v-…

微信小程序实现轮播图

实现轮播图之前必须知道以下三点&#xff1a; 一、轮播图外层容器swiper 二、每一个轮播项swiper-item 三、swiper标签存在默认样式 1. width 100% 2. height 默认为 150px 3 .swiper高度无法实现由内容撑开 默认的150px高度的轮播图如下图: 原图是长这个样子的&#xf…

bootstrap-fileinput(二:编辑(修改)界面文件的上传,回显,删除(数据库同时删除)的操作 )

文章目录bootstrap-fileinput(二&#xff1a;编辑(修改)界面文件的上传&#xff0c;回显&#xff0c;删除(数据库同时删除)的操作 )一、编辑界面文件的上传二、编辑界面文件的回显1.文件的实体类&#xff1a;2.想要回显文件&#xff0c;首先要在工程类(你的编辑界面的主类)里面…

ES6面试问题汇总

面试官通过总问题&#xff0c;ES6方法开始提问 1.ES6有哪些新增方法&#xff1f;/你了解哪些ES6方法&#xff1f;&#xff08;总问题&#xff09; 块级作用域、 模板字符串、 解构赋值、 箭头函数、 函数默认参数、 剩余参数&运算符、 set和map、 import和exprot用…

Vue中实现过渡动画

文章目录Vue的transition动画Transition动画的使用Transition组件的原理Transition动画的classVue的animation动画Animation动画的使用同时设置两种动画(了解)过渡的模式mode列表过渡列表过渡的介绍列表过渡的使用Vue的transition动画 Transition动画的使用 在开发中&#xf…

vite配置cdn优化打包体积

文章目录前言一、版本确认二、使用步骤1.rollup-plugin-visualizer打包体积可视化面板2.配置cdn方法第一种方法&#xff1a; vite-plugin-cdn-import第二种方法&#xff1a; rollup-plugin-external-globals总结前言 大家都知道前端性能优化的方法&#xff0c;cdn外部引入的方…

【微信小程序】小程序知识补充篇

&#x1f381;写在前面&#xff1a; 观众老爷们好呀&#xff0c;这里是前端小刘不怕牛牛频道&#xff0c;小程序系列又更新了呀。 还有就是中秋节就快来啦&#xff0c;程序员过中秋&#xff0c;当然是要好好放松一下啦&#xff0c;那么中秋前我们就不能偷懒了&#xff0c;赶紧学…

Controller层接收前端传参的几种方法。@RequestParam、@RequestBody、@PathVariable。及参数校验。

一、RequestParam 主要用于将请求参数区域的数据映射到控制层方法的参数上 // http://localhost:8080/wh/user/edit?Id9452659856325148452&name天天向上// RequestParam源码Target({ElementType.PARAMETER}) // 只能作用于参数上 Retention(RetentionPolicy.RUNTIME) D…

vue watch监听数据解决新旧值一样的问题(newValue, oldValue)

watch是监听 Vue 实例变化的一个表达式或方法。回调函数得到的参数为新值和旧值。 基础用法 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge…

异步函数async

什么是同步异步 在最新的ES7&#xff08;ES2017&#xff09;中提出的前端异步特性&#xff1a;async、await。 在了解async和await之前得先明白什么是同步函数&#xff0c;什么是异步函数。 同步函数&#xff1a;当一个函数是同步执行时&#xff0c;那么当该函数被调用时不会…

前端CryptoJS和Java后端数据互相加解密(AES)

目录一、序言二、关于前端CryptoJS1、CryptoJS简单介绍2、加密和填充模式选择3、前端AES加解密示例(1) cryptoutils工具类(2) 测试用例(3) 加解密后输出内容说明三、Java后端AES加解密1、Java中支持的加密模式和填充说明2、工具类CryptoUtils3、测试用例一、序言 最近刚好在做…

nodejs——解决跨域问题

目录 1什么是跨域 2解决 1 jsonp(缺点&#xff1a;不能请求post请求&#xff09; 1 index.html页 2 proxy.js页面 搭建一个服务器&#xff08;写好代码后&#xff0c;在cmd上启动&#xff09; 3效果 2服务端代理 &#xff08;由于后端请求不受浏览器同源策略影响&…