最近继续在做NuxtJS+VUE的练习项目,但是某天开始,项目开始出现严重卡顿的情况。这种卡顿不是接口请求过大,也不是页面数据过大,而是就连css的动画效果都能卡死,输入法都能存在好几秒的延迟,直接导致用户体验暴跌(和不能用都没啥区别了)。就这样,为了解决这个问题,我研究了整整一个下午,看了无数的教程,加了交流群,还改了代码,但结果是没有任何卵用,还是非常卡。
我甚至都怀疑是不是我的代码写得太辣鸡了,导致的这种情况,不过好在,一个下午的排查之后,问题解决了。虽然很多教程,还有一些交流群大佬的指点并没有解决问题,但是还是给了很多新的知识点,所以还是留个分析过程方便后续的查阅。
问题是什么
网站的所有操作非常卡顿,加载缓慢,CSS动画卡顿,所有弹窗都有巨大延迟,输入法甚至卡到无法正常输入。
分析过程
1.根据网上的教程,是说可能是内存溢出导致的服务端性能不足,因为Nuxt的特色就是服务端渲染。
我去运行的终端看了下,发现还真有内存溢出。
但是检查了所有的代码,确定了每个插件的引用(其实这里就快接近问题核心了),都没有发现明显的问题。而且最能说明问题的,就是服务器根本没有出现内存和CPU爆满的情况,所以本质上不是内存溢出导致的。
所以排除内存溢出。
2.另一堆教程可能由于不规范的代码,数据量太庞大,或者接口请求太多,或者页面视图更新太频繁导致。
这里首先就排除了数据量和接口请求的问题,因为这尼玛有个jquery写的项目就在运行中,人家框架老但是丝滑如德芙,现在用vue重构反而卡得这个鬼样,接口和数据都是相同的啊,所以我直接怀疑是我代码不规范。
于是,在对整个项目排除的过程中,还顺便修复了几个数据bug,同时修改了一堆地方的定时器。而在这个时候,群里有人说你这个定时器的销毁很不规范,销毁了个寂寞。我的代码是如下:
destroyed(){
var that = this;
clearInterval(that.timer);
that.timer = null;
},
mounted(){
var that = this;
clearInterval(that.timer);
that.timer = null;
}
其实就是在vue的生命周期的页面离开前周期,和页面刚加载完的时候,对定时器进行销毁。但是群里的大佬说,这样是不行的,会销毁不到,然后贴出了如下的代码:
mounted(){
var that = this;
this.$once('hook:beforeDestroy', () => {
clearInterval(that.timer);
that.timer = null;
})
}
并且贴出了github的文章:点击进入
到这里,我恍然大悟,看来是写久了uniapp搞得vue的PC开发都没啥感觉了。于是赶紧修改了整个项目的定时器,就这样....
问题还是没有解决,依然和之前没有任何区别。
3.前两个都没有解决问题,我有点怀疑人生,但是再看了一些网上的文章之后,我觉得,有没有一种可能性,并不是我的问题?
于是,我打开了之前在本地的项目备份,并将它运行起来,结果震惊的发现,这个几天前的备份包访问起来丝滑如德芙(比jquery那个老项目还丝滑)。
就这样,我开始分析两个项目的差异,发现和几天前的相比,本质上就多了一个store持久化插件和整理了一些测试的语言包。所以我直接卸载了store持久化插件,发现没有卵用。
然后我删除了一些语言包json的引用,结果发现,居然没那么卡了,虽然还是掉帧和输入框延迟,但是能用了!!
是的,问题就是语言包导致的,准确的说是vue-i18n这个插件。很快,我就回忆起了一个细节,因为我项目的vue版本是2.6.14,无法安装vue-i18n的最新版,所以就安装了一个老的版本,而在查询内存溢出问题的时候,网上有文章提到过,插件是可能导致项目内存溢出和卡顿。
所以先升级了vue版本到2.7.10,然后升级到vue-i18n到8.27.2(也就是这个vue兼容的最大版本)
再次运行项目,问题解决。
浪费了我一个下午时间