自己的思路:先不做任何优化,试一下打包后有多大, 然后通过逐步优化看一下对打包尺寸的影响。
先在package.json中设置多环境的脚本
"serve-dev": "vue-cli-service serve --mode dev --port 8080",
"serve-prod": "vue-cli-service serve --mode prod",
"build-dev": "vue-cli-serve build --mode dev",
"build-prod": "vue-cli-serve build --mode prod",
打包结果
0. 先阅读一下官方文档「性能优化」部分
官方文档有一部分就是关于性能优化的,可以读一读这部分
这部分提到web应用性能的两个方面是:
-
页面加载性能:首次访问时,页面呈现出可交互状态的速度。这部分性能通常用Google 所定义的一系列指标来衡量,比如Largest Contentful Paint、First Input Delay
-
更新性能:应用响应用户的速度。比如搜索框输入后列表更新的速度,跳转页面的切换速度。
理想情况下两者都应该最大化,但是前端架构会影响它们能达到的程度。所以优化性能的第一步是为应用确定合适的架构。
官方文档中提到的优化方法主要有:
- 给项目确定何时的架构。
- 做代码分割,按需导入;
- 让子组件prop尽量保持稳定;可以尝试使用
v-oncev-memo指令。 - 用列表虚拟化提高大型列表的速度(可以使用组件)
- 避免不必要的组件抽象。组件实例比普通 DOM 节点要昂贵得多,而且为了逻辑抽象创建太多组件实例将会导致性能损失。=> 这点在组件实例非常多的时候表现比较明显,例如有1万个数据,每个都需要渲染一个组件。
官方文档中的主要要点感觉就是这些,说的比较笼统一些。
参考一些资料,给自己的项目做一下优化。
1. 路由懒加载
可以參考一下官方文檔
When building apps with a bundler, the JavaScript bundle can become quite large, and thus affect the page load time. It would be more efficient if we can split each route's components into separate chunks, and only load them when the route is visited.
这段话的要点是:我们用bundler来构建项目时,生成的bundle可能会很大,影响页面载入速度。如果把每个route的组件分割成不同的chunk,然后当路径被访问时,对应的组件才被加载,这样可以提高速度。
可以看出,这个方法对应的是官方文档中的方法2-做代码分割,按需导入。
设置方法是:将原本的静态导入改成动态导入。
// replace
// import UserDetails from './views/UserDetails'
// with
const UserDetails = () => import('./views/UserDetails.vue')
const router = createRouter({
// ...
routes: [{ path: '/users/:id', component: UserDetails }],
})
官方文档说
In general, it's a good idea to always use dynamic imports for all your routes.
也就是说一般情况应该保持使用动态路由导入。
把自己项目的路由都变成懒加载后,发现dist里的js确实被拆分成了更多片段。对比上面的图,之前只有两个文件。
在vue可视化界面中,可以看到文件尺寸还是过大。而且第三库占据了很大比例。所以接下来打算从第三方包入手优化性能。
2. 第三方库的优化
我需要再检查一下是否有安装了但并未使用的包。
可以用depcheck来帮助检查。
流程:
npm install -g depcheck
depcheck [directory] [arguments] // 如果是在项目目录下,直接depcheck就可以了
这方面我做的事有:
- 把emoji包删掉(这个包只在日记模块有使用,但是这个emoji本身载入效果就很慢,效果也不理想,而且这个功能低调到我自己都会忘记,所以删掉了表情包的处理)
- 删掉了一些没使用的包。比如yup、lodash、moment(后来用dayjs替换了)、vee-validate
然后用webpack-bundle-analyzer这个插件看一下第三库的具体情况,这个包vuejs官方已经集成了,所以可以直接懒人操作。具体参考这篇文章。
1.执行如下命令
npm run build -- --report
然后在dist文件夹下就会生成report.html这个文件。直接查看就可以了。
可以很直观地看出:apexchart首先就很碍眼...然后是cos-js-sdk,然后是element-plus。 从这三个入手看看能不能cdn加载...
(1) cos-js-sdk
这个官网上就有cdn的地址:官方文档 然后cdn引入的话,还需要在配置文件中加个文件。说实话这部分配置文件怎么写我之前一直搞不太清楚,今天终于明白了。
之前在配置文件的externals属性中配置时,我主要不明白key、value具体写什么都到哪里找信息,网络搜索时搜到的文章基本都不解释,今天运气好搜到这篇文章终于明白了。
也就说key的部分是我们写import的时候的那个包名,而value是全局变量名字。
之前不明白这点时,当想引入一个新库时,根本不知道怎么写,只能尝试到网络上搜索。明白这点后今天可以独立配置了。
例如:cos-js-sdk配置时key当然就写cos-js-sdk, 而value是cos-js-sdk的全局变量,全局变量名字官方文档直接就有写是“COS"。
所以它的配置是:
'cos-js-sdk-v5': 'COS'
(2)element-plus
我用的element-plus不是最新版,所以我需要找到我用到的版本的cdn地址。这个引入花了好长时间。
总之引入后就是没有效果。报错
网上查似乎是说它用了commonJs写法所导致的。 这块研究了四五个小时,最终没有结果...以后遇到技术大大再问问。所以这个先不用cdn导入了。
(3)apex-charts
apex-charts的引入也花了很长时间。它引入需要两个包,一个是apex-charts,一个是vue3-apexcharts, 一直报错,我比较怀疑是后者全局变量写错的原因,自己看了下源码感觉就是vueApexCharts,但一直报错,网络上也搜不到。但是自己发现:vue3-apexcharts的包很小(文件内容也能看出来非常少),其实比较占空间的是前者,于是我把前者用cdn引入,后者正常npm安装,发现成功了,也达到了压缩体积的目的。
3. 图片资源压缩
我主要是用tinypng.com 这个网站把项目里用的图片都压缩了一下。