提高 Vue 中的 $destroy 性能
简介 在大多数情况下,Vue 是一个足够快的框架。但是,节点销毁的时间可能很长。当然,从 DOM 中删除元素是快速操作,但 Vue 需要从 destruct 组件中删除所有观察者,这可能需要几秒钟。 案例 具有 12 个组的嵌套导航组件,每个组有约 20 个子项。打开所有组后,导航有大约 240 个项目。用户尝试导航到另一个视图后,浏览器会冻结几秒钟。 Navigation - Group x12
简介
在大多数情况下,Vue 是一个足够快的框架。但是,节点销毁的时间可能很长。当然,从 DOM 中删除元素是快速操作,但 Vue 需要从 destruct 组件中删除所有观察者,这可能需要几秒钟。
案例
具有 12 个组的嵌套导航组件,每个组有约 20 个子项。打开所有组后,导航有大约 240 个项目。用户尝试导航到另一个视图后,浏览器会冻结几秒钟。
Navigation
- Group x12
- Item x20
进入全屏模式 退出全屏模式
调查
打开 chromium 开发工具,转到性能部分并设置 CPU:在该浏览器将像在普通用户计算机上一样运行后慢 4 倍。
[](https://res.cloudinary.com/practicaldev/image/fetch/s--m1x5BgzU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/guiiygayerpuo3uew59u.png)
然后记录破坏导航。结果:
[](https://res.cloudinary.com/practicaldev/image/fetch/s--eEx3hQ-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/azyw3ysmrl5fsvhi204v.png)
Oh my God 几乎 7 秒的销毁和 0.65 秒的更新(销毁前)o.O
[](https://res.cloudinary.com/practicaldev/image/fetch/s--SFEnWkAL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/o5rzo860lw9d32x336ed.png)
在主$destroy
中有许多较短的 $destroy 并且它们都有许多 removeSub 调用。removeSub
中的每一个都需要 7-15 毫秒,虽然不多,但总的来说,浏览器冻结的时间很长。
原因
组件Item.vue
绑定到 5 个高阶 vuex getter,渲染了大约 240 次。
// Item.vue
...mapGetters('namespace', [
'getA',
'getB',
'getC',
'getD',
'getE',
});
进入全屏模式 退出全屏模式
Item.vue
也有 8 个计算属性,其中 5 个使用 vuex getter。所有这些操作并不昂贵,但是会创建许多订阅。这些订阅必须被清除。
解决方案
将所有计算的 props 和 vuex 绑定从Item.vue
移动到Group.vue
。Group.vue
正在渲染许多Item.vue
,所以我们必须像这样映射项目集合:
结果
[](https://res.cloudinary.com/practicaldev/image/fetch/s--CaushTWH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/8wxlk6973yqouzwj1f1t.png)
$destroy
的时间从约 7 秒减少到 0.3 秒 (-96%)。还更新之前它从 0.65 秒减少到 0.45 秒(-30%)。请注意,这不是一个完美的解决方案:因为映射器应该移动到Navigation.vue
添加 passGroup.vue
作为道具。然而,移动计算 a、b、c、d、e 将“仅”将绑定减少 55 (12 * 5 – 5)。这种表现不是很好,但也不可怕。
结论
在 vue 中,将数据从 store 加载到组件非常简单:只有...mapGetters('namespace', ['getter'])
,但并非所有组件都应该知道 store。在 React 的钩子非常流行之前,编写容器将来自 Redux 的数据通过mapStateToProps
和mapDispatchToPros
与组件连接起来。这是很多样板,谢天谢地,我们现在可以使用useReducer
,但它有一个优点:让开发人员考虑将与 store 的连接放在哪里。在我看来,我们仍然必须关心它,因为将组件分离为逻辑和表示不仅对于保持代码清洁而且对于性能目的也很重要。
更多推荐
所有评论(0)