Vite打包性能优化及填坑

最近在使用 Vite4.0 构建一个中型前端项目的过程中,遇到了一些坑,也做了一些项目在构建生产环境时的优化,在这里做一个记录,以便后期查阅。(完整配置在后面)

上面是dist文件夹的截图,里面的内容已经有30mb了,是时候该做点什么了。

分析

想要实现优化,首先我得先知道,是什么占了这么大的空间。是图片?是库?还是其他静态资源?

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

    js
    复制代码build: {rollupOptions: {output: {chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称entryFileNames: 'js/[name]-[hash].js', // 包的入口文件名称assetFileNames: '[ext]/[name]-[hash].[ext]', // 资源文件像 字体,图片等}}
    }
    
  2. 查看项目的依赖,找出大块头

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

bash
复制代码npm i rollup-plugin-visualizer -D
js
复制代码import { visualizer } from 'rollup-plugin-visualizer'
js
复制代码plugins: [visualizer({open: true})
]
arduino
复制代码npm run build // 打包结束后会出现下图

 

从体积能看到,这里已经达到了7MB大小了,是时候该做点什么了。

优化

拆分包

这里有一个自己的个人见解:如果不同模块使用的插件基本相同那就尽可能打包在同一个文件中,减少http请求,如果不同模块使用不同插件明显,那就分成不同模块打包。这是一个矛盾体。这里使用的是最小化拆分包。如果是前者可以直接选择返回'vendor'。

scss
复制代码rollupOptions: {output: {manualChunks(id) {if (id.includes("node_modules")) {// 让每个插件都打包成独立的文件return id .toString() .split("node_modules/")[1] .split("/")[0] .toString(); }}}
}

去除debugger

bash
复制代码npm i terser -D
js
复制代码terserOptions: {compress: {drop_console: true,drop_debugger: true}
}

CDN 加速

内容分发网络(Content Delivery Network,简称 CDN)就是让用户从最近的服务器请求资源,提升网络请求的响应速度。同时减少应用打包出来的包体积,利用浏览器缓存,不会变动的文件长期缓存。(不建议使用第三方cdn,这里做学习讨论使用)

bash
复制代码npm i rollup-plugin-external-globals -D
npm i vite-plugin-html -D
html
复制代码<head><%- vuescript %>
</head>
css
复制代码import { createHtmlPlugin } from 'vite-plugin-html'rollupOptions: {// 告诉打包工具 在external配置的 都是外部依赖项  不需要打包external: ['vue'],plugins: [externalGlobals({// "在项目中引入的变量名称":"CDN包导出的名称,一般在CDN包中都是可见的"vue: 'Vue'})]
}plugins: [createHtmlPlugin({minify: true,inject: {data: {vuescript: '<script src="https://cdn.jsdelivr.net/npm/vue@3.2.37"></script>'}}})
]

 

按需导入

仔细看上面那张图右下部分的模块,不知道你会不会感觉到奇怪,明明是同一个包,为什么既出现了lodash又出现了lodash-es。其实lodash-es 是 lodash 的 es modules 版本 ,是着具备 ES6 模块化的版本,体积小,而lodash是common.js版本。lodash最大的缺陷就是无法按需导入。

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

项目中用到lodash的地方也不多,经过手动修改一下,看现在已经看不到lodash的库了。

文件压缩

复制代码npm install vite-plugin-compression -D
js
复制代码// 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 压缩。

图片压缩

bash
复制代码yarn add vite-plugin-imagemin -D

or

bash
复制代码npm i vite-plugin-imagemin -D
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}]}})
]

viteImagemin在国内比较难安装,容易出现报错,可以尝试一下下面几种解决方案。

viteImagemin报错

  1. 使用 yarn 在 package.json 内配置(推荐) "resolutions": { "bin-wrapper": "npm:bin-wrapper-china" }

  2. 使用 npm,在电脑 host 文件加上如下配置即可 199.232.4.133 raw.githubusercontent.com

  3. 使用 cnpm 安装(不推荐)

填坑

坑1

在优化过程中发现有什么rollupOption不生效,请检查vite版本。上述配置在vite4.0版本生效,如需升级,请前往官方迁移文档。

坑2

Uncaught TypeError: Failed to resolve module specifier "Vue". Relative references must start with either "/", "./", or "../".

图片

这里有可能是 vue-demi 引入了 vue,然而 rollup-plugin-external-globals 插件配置全局变量时不会处理 node_modules 下的依赖项,导致 vue-demi 还是通过 import 的方式与 node_modules 下的 vue 进行关联,而没有使用全局变量下的 vue,打包后 vue 已变成外部依赖项,vue-demi 自然无法找到 vue,所以就报错了。

vue-demi是哪里来的呢,我的项目是由于element-plus引用了vue-demi,所以此时解决方案就是将vue-demi也用cdn引入。

总结

到了这一步,整个文件夹已经完全瘦身了。从一开始的30MB到现在的11.8MB了。我们在项目里面放置了许多json数据(因为业务原因不能上传到服务器),json数据已经占了差不多5、6mb的原因,所以是一个单纯的项目并没有这么大。

 

 

配置

js
复制代码// vite.config.js
import { defineConfig } from 'vite'
import { createHtmlPlugin } from 'vite-plugin-html'
import viteImagemin from 'vite-plugin-imagemin'
import externalGlobals from 'rollup-plugin-external-globals'
import { visualizer } from 'rollup-plugin-visualizer'
import viteCompression from 'vite-plugin-compression'
// https://vitejs.dev/config/
export default defineConfig({plugins: [visualizer({ open: true }),// 将下面的添加到plugin下createHtmlPlugin({minify: true,inject: {data: {vuescript: '<script src="https://cdn.jsdelivr.net/npm/vue@3.2.25"></script>',demiScript: '<script src="//cdn.jsdelivr.net/npm/vue-demi@0.13.7"></script>',elementPlusScript: `<link href="https://cdn.jsdelivr.net/npm/element-plus@2.2.22/dist/index.min.css" rel="stylesheet"><script src="https://cdn.jsdelivr.net/npm/element-plus@2.2.22/dist/index.full.min.js"></script>`,echartsSciprt: '<script src="https://cdn.jsdelivr.net/npm/echarts@5.0.2/dist/echarts.min.js"></script>'}}}),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}]}})],build: {target: 'es2020',minify: 'terser',// rollup 配置rollupOptions: {output: {chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称entryFileNames: 'js/[name]-[hash].js', // 包的入口文件名称assetFileNames: '[ext]/[name]-[hash].[ext]', // 资源文件像 字体,图片等manualChunks(id) {if (id.includes('node_modules')) {return 'vendor'}}},//  告诉打包工具 在external配置的 都是外部依赖项  不需要打包external: ['vue', 'element-plus', 'echarts'],plugins: [externalGlobals({vue: 'Vue','element-plus': 'ElementPlus',echarts: 'echarts','vue-demi': 'VueDemi'}),viteCompression({verbose: true, // 是否在控制台中输出压缩结果disable: false,threshold: 10240, // 如果体积大于阈值,将被压缩,单位为b,体积过小时请不要压缩,以免适得其反algorithm: 'gzip', // 压缩算法,可选['gzip',' brotliccompress ','deflate ','deflateRaw']ext: '.gz',deleteOriginFile: false // 源文件压缩后是否删除})]},terserOptions: {compress: {// 生产环境时移除consoledrop_console: true,drop_debugger: true}}}
})

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Revit SDK:SpatialFieldGradient 在面上显示渐变颜色(AVF)分析显示样式

前言 这个例子使用Revit显示样式功能将面显示成不同的颜色。分析显示样式参考官方文档。 内容 效果&#xff1a; 核心逻辑&#xff1a; 得到一个 SpatialFieldManager拾取一系列的面&#xff1a;uiDoc.Selection.PickObjects(ObjectType.Face)计算面上的 UV 值&#xff0c;…

COSCon'23 开源市集:共赴一场草坪上的开源派对

一年一度的开源盛会&#xff0c;第八届中国开源年会&#xff08;COSCon23 &#xff09;&#xff0c;将于10月28~29日&#xff0c;在四川成都市高新区菁蓉汇召开&#xff01;本次大会的主题是&#xff1a;“开源&#xff1a;川流不息、山海相映”&#xff01; 我们预期会有超过1…

更健康舒适更科技的照明体验!SUKER书客护眼台灯 L1上手体验

低价又好用的护眼台灯是多数人的需求&#xff0c;很多人只追求功能性护眼台灯&#xff0c;显色高、无频闪、无蓝光等基础需求。但是在较低价格中很难面面俱到&#xff0c;然而刚发布的SUKER书客L1护眼台灯却是一款不可多得的性价比护眼台灯&#xff0c;拥有高品质光源&#xff…

第63步 深度学习图像识别:多分类建模误判病例分析(Tensorflow)

基于WIN10的64位系统演示 一、写在前面 上两期我们基于TensorFlow和Pytorch环境做了图像识别的多分类任务建模。这一期我们做误判病例分析&#xff0c;分两节介绍&#xff0c;分别基于TensorFlow和Pytorch环境的建模和分析。 本期以健康组、肺结核组、COVID-19组、细菌性&am…

mp代码生成插件

mp代码生成插件 1.下载下面的插件 2.连接测试 3.生成代码的配置 4.生成代码 红色的是刚刚生成的。 我觉得不如官方的那个好用&#xff0c;唯一的好处就是勾选的选项能够看的懂得。

视频云存储/安防监控/AI视频智能分析网关V3:工服检测功能详解

在一些工地、后厨、化工、电力等特定的场景中&#xff0c;工服的穿戴是必不可少的。这不仅是安全制度的要求&#xff0c;更能降低工作风险、提高工作效率。TSINGSEE青犀AI 边缘计算网关硬件 —— 智能分析网关可以通过实时监测和识别工人的工装穿戴情况&#xff0c;确保他们符合…

什么是接口测试,如何做接口测试?

比起点点点的功能测试&#xff0c;“接口测试”显得专业又高大上&#xff0c;也因此让有些初级测试人员“望而生畏”。别担心&#xff0c;其实接口测试也是功能测试的一种&#xff0c;它是针对接口进行的功能测试。 写在前面&#xff1a;本文参考了茹炳晟老师的《测试工程师 全…

软件架构设计(三) B/S架构风格-层次架构(一)

层次架构风格从之前的两层C/S到三层C/S,然后演化为三层B/S架构,三层B/S架构之后仍然在往后面演化,我们来看一下层次架构演化过程中都有了哪些演化的架构风格呢? 而我们先简单了解一下之前的层次架构风格中分层的各个层次的作用。 表现层:由于用户进行交互,比如MVC,MVP,…

医院小程序如何在线搭建?实战解析

在当今数字化时代&#xff0c;移动应用程序成为我们生活中必不可少的一部分。特别是在医疗领域&#xff0c;移动应用程序的需求更为迫切。为了满足这一需求&#xff0c;开发一个医疗小程序成为了许多医疗机构的优先选择。 在本文中&#xff0c;我们将分享一个实战攻略&#xff…

大数据可视化大屏实战项目(3)图书销售展示全国地图可视化---HTML+CSS+JS【源码在文末】(可用于比赛项目或者作业参考中)

大数据可视化大屏实战项目&#xff08;3&#xff09;图书销售展示全国地图可视化---HTMLCSSJS【源码在文末】&#xff08;可用于比赛项目或者作业参考中&#x1f415;&#x1f415;&#x1f415;&#xff09; 一&#xff0c;项目概览 ☞☞☞☞☞☞项目演示链接&#xff1a;http…

实力认证!OceanBase获“鼎信杯”优秀技术支撑奖

6 月 30 日&#xff0c;2023 “鼎信杯”信息技术发展论坛在京隆重举办第二届“鼎信杯”大赛颁奖典礼。OceanBase 凭借完全自主研发的原生分布式数据库&#xff0c;以及丰富的核心系统国产数据库升级案例&#xff0c;斩获“优秀技术支撑奖”。 论坛上&#xff0c;国内首个基于在…

打车系统网约车系统开发支持APP公众号H5小程序版本源码

一、操作流程 二、业务模式 三、用户端 用户注册登录&#xff1a;未注册的手机号将自动创建账号 通过好友的邀请链接进行注册&#xff0c;将会绑定上下级关系 也可以注册的时候输入好友的邀请码&#xff0c;也可以绑定关系 用户充值&#xff1a; 用户下单支付时&#xff0c;可以…

【大数据】数据湖:下一代大数据的发展趋势

数据湖&#xff1a;下一代大数据的发展趋势 1.数据湖技术产生的背景1.1 离线大数据平台&#xff08;第一代&#xff09;1.2 Lambda 架构1.3 Lambda 架构的痛点1.4 Kappa 架构1.5 Kappa 架构的痛点1.6 大数据架构痛点总结1.7 实时数仓建设需求 2.数据湖助力于解决数据仓库痛点问…

《Flink学习笔记》——第十一章 Flink Table API和 Flink SQL

Table API和SQL是最上层的API&#xff0c;在Flink中这两种API被集成在一起&#xff0c;SQL执行的对象也是Flink中的表&#xff08;Table&#xff09;&#xff0c;所以我们一般会认为它们是一体的。Flink是批流统一的处理框架&#xff0c;无论是批处理&#xff08;DataSet API&a…

基于RabbitMQ的模拟消息队列之三——硬盘数据管理

文章目录 一、数据库管理1.设计数据库2.添加sqlite依赖3.配置application.properties文件4.创建接口MetaMapper5.创建MetaMapper.xml文件6.数据库操作7.封装数据库操作 二、文件管理1.消息持久化2.消息文件格式3.序列化/反序列化4.创建文件管理类MessageFileManager5.垃圾回收 …

钡铼R40边缘计算网关与华为云合作,促进物联网传感器数据共享与应用

场景说明 微型气象是不可预测的&#xff0c;基本上不能通过人工手段来分析其变化&#xff0c;因此必须运用新技术&#xff0c;对气象进行实时监测&#xff0c;以便采取相应的措施来避免或解决事故的发生。而常规气象环境数据采集容易造成数据损失、人力成本高、数据安全性差、…

基础算法-递推算法-学习

现象&#xff1a; 基础算法-递推算法-学习 方法&#xff1a; 这就是一种递推的算法思想。递推思想的核心就是从已知条件出发&#xff0c;逐步推算出问题的解 最常见案例&#xff1a; 一&#xff1a;正向递推案例&#xff1a; 弹力球回弹问题&#xff1a; * 弹力球从100米高…

Axes3D绘制3d图不出图解决办法【Python】

运行下面一段代码​&#xff1a; import numpy as npimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d import Axes3D#这里设函数为y3x2x_data [1.0,2.0,3.0]y_data [5.0,8.0,11.0]​def forward(x): return x * w b​def loss(x,y): y_pred forward(x) …

螺旋矩阵、旋转矩阵、矩阵Z字打印

螺旋矩阵 #include <iostream> #include <vector> void display(std::vector<std::vector<int>>&nums){for(int i 0; i < nums.size(); i){for(int j 0; j < nums[0].size(); j){std::cout<<nums[i][j]<< ;}std::cout<<…

VueRouter的基本使用

路由的基本使用 文章目录 路由的基本使用01-VueRouterVueRouter的使用 &#xff08; 5 2&#xff09;综合代码 拓展&#xff1a;组件存放问题 什么是路由呢&#xff1f; 在生活中的路由&#xff1a;设备和IP的映射关系 在Vue中&#xff1a;路径 和 组件 的 映射 关系。 01-Vu…