网站首页 > 博客文章 正文
最近一段时间一直在处理公司的一个内部项目哈,因为页面卡的问题被吐槽了一个月了。因为是接手别人的项目,虽然说不是自己直接造成的。但是解决这个问题已是迫在眉睫了。
可能我们在做前端开发的时候,很少去关注内存的问题,这是因为JS有自己垃圾回收机制,如果代码不是滥用闭包,一般来说,不会出现性能问题。
先来大概说下我的项目中性能瓶颈的现象:项目是一个基于electron+vue的一个类似微信桌面端的项目,因为是公司项目就不截图了,想象是微信就行了。
当我们切换左侧联系人列表的时候,发现内存不断的上升,而且很难降下来,很典型的内存泄露了。
时间一长,内存吃完了,程序直接崩了。。。
好吧,解决问题吧,知道有内存泄露,我们一般会找项目中的代码是不是有没有及时释放的闭包局部变量。
但是,效果不明显。
我的解决方案
1、查看当前页面的dom节点数。
一般来说在3000左右是为正常吧。这个如果查看呢?
很简单,我们只需要在浏览器控制台输入:
$("*")
即可!
当我在我的项目中输入的时候,节点达到了10000+了,好家伙,问题找到了,原来是dom渲染太多了?
这应该是一个瓶颈吧,接下来不是去掉多余的dom了,我发现在渲染列表的时候,一些很多的原点是没有必要时时渲染的,还有一些dom是通过v-show来隐藏起来的。
慢慢的把这些问题解决了,dom节点降下来了。内存是得到了很好的控制。
你们以为这就完了吗?
但是随着列表的切换,内存还是会上升,只是没那么明显了。
What??
你们说气人不?没办法,还得继续优化了。
这时候,我们要结合我的第一种方案,形成第二种方案。
2、优化渲染列表本身。
一般来说,我们列表的数据是通过后端或者本地数据库获取到的一个数组对象,而数组的每一项一般都是一个Json对象。我们是直接将这个数据对象挂载到组件的data对象或者vuex中去。
不管是哪种方案,在读过vue源码后,知道他是存在一问题的。
首先,我们的组件的data对象下数据,vue为了双向数据绑定,会给每一个属性添加get和set函数。也就是说。一个数据对象所有的属性都会添加一次get和set,但是如果说我们的列表中的数据不需要数据响应,那这个get和set是没有意义的。
好了,有这个思路,我们应该要想办法不让vue去给这个列表数据添加get和set。那该怎么做呢?
要么说阅读源码很重要呢?因为我之前看过数据响应的相关源码哈,我就直接带大家看一眼吧。
在defineReactive方法中,它是专门用来定义get和set的,我们可以看到有一个情况他是不进行get和set的,当对象的configable为false的时候。
一般来说,一个对象的configurable属性为false的时候。
好像看到希望了
在ES5中,Object对象下有一个方法可以!!!
Object.freeze ,它可以将一个对象冻结起来。
当我们用Object.freeze将对象冻结的时候,我们再来看效果
结果一目了然了吧。
好了,接下来我们将我们要渲染的列表用Object.freeze来冻结。再来看效果。
果不其然,内存下来了,正常了。。。哈哈哈
问题来了,当我们把对象冻结后,如果我们想去修改数组中的某一项的数据的时候,这时候我们是无法直接修改的。这时候,我们需要先将冻结后的数组拿到,然后通过[...list];进行解冻。然后修改,然后将新的数组重新冻结再去更新data或者 vuex! 完美解决。
技术总结:
在排查问题的同时,我先考虑了本地数据库的性能问题,排除后再去排查ui的问题。
我们在vue项目开发的时候,一定要注意我们看不到的页面不要渲染无效的dom结构,要想提高列表的渲染性能,Object.freeze能大大帮助们提高页面性能。
从排查问题,到解决问题,过程是痛苦的,但是当问题被解决的时候,被用户肯定的时候,这些都值了。。
如果大家还有其它更好的优化方案,评论区告诉我下啊。
这里是畅哥聊技术,欢迎关注,坚持将自己的一线开发经验形成技术文章,希望能帮助到大家。
全文完!
猜你喜欢
- 2025-03-24 离线环境下运行Vue项目(vue离线安装插件)
- 2025-03-24 学会就能接项目!Vue + Spring Boot 实现全栈商城项目开发
- 2025-03-24 vue项目运行过程梳理(vue项目实战教程)
- 2025-03-24 VUE3.0 创建项目、打包(vue3.0打包配置)
- 2025-03-24 推荐10个基于Vue3.0全家桶的优秀开源项目
- 2025-03-24 Vue3+Django4全新技术实战全栈项目(完结)
- 2025-03-24 Nginx部署Vue项目以及解决刷新页面404
- 2025-03-24 基于 Vue3.0 知乎专栏示例项目Vue3-Zhihu
- 2025-03-24 一篇文章说清 webpack、vite、vue-cli、create-vue 的区别
- 2025-03-24 抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
你 发表评论:
欢迎- 374℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 369℃用AI Agent治理微服务的复杂性问题|QCon
- 360℃初次使用IntelliJ IDEA新建Maven项目
- 353℃Maven技术方案最全手册(mavena)
- 351℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 349℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 348℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 344℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)