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.mzph.cn/news/67702.shtml

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

相关文章

【广州华锐互动】利用AR远程指导系统进行机械故障排查,实现远程虚拟信息互动

随着工业自动化和智能化的不断发展&#xff0c;机械故障诊断已经成为了工业生产中的重要环节。为了提高故障诊断的准确性和效率&#xff0c;近年来&#xff0c;AR&#xff08;增强现实&#xff09;远程协助技术逐渐应用于机械故障诊断领域。本文将探讨AR远程协助技术在机械故障…

NPM 常用命令(三)

目录 1、npm compltion 1.1 描述 2、npm config 2.1 常用命令 2.2 描述 set get list delete edit fix 2.3 配置 json global editor location long 3、npm dedupe 3.1 描述 3.2 配置 4、npm deprecate 4.1 命令使用 4.2 描述 4.3 配置 registry ot…

字节二面:如果高性能渲染十万条数据?

前言 最近博主在字节面试中遇到这样一个面试题&#xff0c;这个问题也是前端面试的高频问题&#xff0c;作为一名前端开发工程师&#xff0c;我们虽然可能很少会遇到后端返回十万条数据的情况&#xff0c;但是了解掌握如何处理这种情况&#xff0c;能让你对前端性能优化有更深的…

Logback日志记录只在控制台输出sql,未写入日志文件【解决】

原因&#xff1a;持久层框架对于Log接口实现方式不一样&#xff0c;日记记录的位置及展示方式也也不一样 mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # sql只会打印到控制台不会输出到日志文件种mybatis-plus:configuration:log-impl…

31 WEB漏洞-文件操作之文件包含漏洞全解

目录 文件包含漏洞原理检测类型利用修复 本地包含-无限制&#xff0c;有限制远程包含-无限制&#xff0c;有限制各种协议流玩法文章介绍读取文件源码用法执行php代码用法写入一句话木马用法每个脚本支持的协议玩法 演示案例某CMS程序文件包含利用-黑盒CTF-南邮大&#xff0c;i春…

定时任务job (现成直接用)

1. 任务调度的2种方式 1. bean调用示例: 对应的类上加Component或Service注解, 类名.方法名(ryTask.ryNoParams) 类名首字母小写; 该类必须要在com.ruoyi 包下, 因为有校验 2. 权限类名调用示例: com.ruoyi.quartz.task.RyTask.ryNoParams 注意: class(类名)调用的时候, 只能调…

leetcode 35. 搜索插入位置

2023.9.4 本题较为简单&#xff0c;题目要求O(log n)的时间复杂度&#xff0c;就不能遍历查找了&#xff0c;得用二分查找。若成功查找到target值&#xff0c;则直接返回索引&#xff1b; 若直到结束都没查找到则返回left值。(纸上模拟下就懂了) 代码如下&#xff1a; class S…

Axure RP PC电商平台Web端交互原型模板

Axure RP PC电商平台Web端交互原型模板。原型图内容齐全&#xff0c;包含了用户中心、会员中心、优惠券、积分、互动社区、运营推广、内容推荐、商品展示、订单流程、订单管理、售后及服务等完整的电商体系功能架构和业务流程。 在设计尺寸方面&#xff0c;本套模板按照主流的…

酷派30/锋尚40/大观40S首发解锁BL+完美root权限+去除密码黑砖线刷修复

早前的中华酷联&#xff0c;随着时代的发展&#xff0c;酷派手机虽热发展的并没有其他手机那么快&#xff0c;但也 是坚强的活了下来。目前主打机型为Cool系列&#xff0c;最高为Cool30机型&#xff0c;并且发布酷派锋尚 40酷派大观40S&#xff0c;起头并进。该系列机型&#x…

Web前端开发概述

Web&#xff08;World Wide Web&#xff0c;全球广域网&#xff09;是指一种基于互联网的信息系统&#xff0c;通过超文本链接将全球各地的文档、图像、视频等资源相互关联起来&#xff0c;并通过Web浏览器进行交互浏览和访问。Web的发展使得人们可以方便地获取和共享各种类型的…

【搭建私人图床】使用LightPicture开源搭建图片管理系统并远程访问

文章目录 1.前言2. Lightpicture网站搭建2.1. Lightpicture下载和安装2.2. Lightpicture网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 现在的手机越来越先进&#xff0c;功能也越来越多&#xff0c;而手机…

Redis——数据结构介绍

Redis是一个key-value的数据库&#xff0c;key一般是String类型&#xff0c;不过value的类型是多样的&#xff1a; String&#xff1a;hello wordHash&#xff1a;{name:"Jack",age:21}List&#xff1a;[A -> B -> C -> D]Set&#xff1a;{A,B,C}SortedSet…

uni-app 之 图片

uni-app 之 图片 获取图片 v-bind 动态绑定 image.png <template><view><view>--- 获取图片1 ---<image src"../../static/img/tabbar_home1.png"></image></view><view>--- 获取图片2 v-bind 动态绑定---<image v-bi…

面试题查漏补缺 i++和 ++ i哪个效率更高

i 和 i 哪个效率更高&#xff1f; 在这里声明&#xff0c;简单地比较前缀自增运算符和后缀自增运算符的效率是片面的&#xff0c;因为存在很多因素影响这个问题的答案。首先考虑内建数据类型的情况:如果自增运算表达式的结果没有被使用&#xff0c;而是仅仅简单地用于增加一员…

从本地到Gitee:一步步学习文件上传及解决常见报错问题

&#x1f642;博主&#xff1a;小猫娃来啦 &#x1f642;文章核心&#xff1a;一步步学习文件上传及解决常见报错问题 文章目录 安装git进入gitee官网&#xff0c;登录账号新建仓库先打开git命令行上传本地资源到仓库第一步&#xff1a;git init第二步&#xff1a;git add .第三…

Revit SDK 介绍:CreateAirHandler 创建户式风管机

前言 这个例子介绍如何通过 API 创建一个户式风管机族的内容&#xff0c;包含几何和接头。 内容 效果 核心逻辑 必须打开机械设备的族模板创建几何实体来表示风管机创建风机的接头 创建几何实体来表示风管机 例子中创建了多个拉伸&#xff0c;下面仅截取一段代码&#xff…

开发指导—利用 CSS 动画实现 HarmonyOS 动效(二)

注&#xff1a;本文内容分享转载自 HarmonyOS Developer 官网文档 点击查看《开发指导—利用CSS动画实现HarmonyOS动效&#xff08;一&#xff09;》 3. background-position 样式动画 通过改变 background-position 属性&#xff08;第一个值为 X 轴的位置&#xff0c;第二个…

go web之一:hello world快速上手+handle(http.Handle和http.HandleFunc的区别与联系)

前情提要&#xff1a; 需要安装好go的环境和VSCode的go插件。 hello world快速上手 1、创建go.mod 在项目根目录下打开命令行&#xff0c;或者直接用VSCode中的终端。输入命令 go mod init github.com/solenovex/web-tutorial 然后就能看到项目结构中多了一个go.mod 2、…

JavaWeb知识梳理(后端部分)

JavaWeb 静态web资源&#xff08;如html 页面&#xff09;&#xff1a;指web页面中供人们浏览的数据始终是不变。 动态web资源&#xff1a;指web页面中供人们浏览的数据是由程序产生的&#xff0c;不同时间点访问web页面看到的内容各不相同。 静态web资源开发技术&#xff1…

2023年特色小镇行业研究报告

第一章 行业概况 1.1 定义 特色小镇&#xff0c;是指以特定产业、文化、旅游、历史等特色为依托&#xff0c;以小镇为载体&#xff0c;通过优化提升小镇的综合功能和服务能力&#xff0c;形成独特的区域品牌和产业集群&#xff0c;进而推动区域经济社会发展的一种新型城镇化形…