从后台获取的数据量过大时,加载页面会出现内存溢出的问题

1,329 阅读4分钟

记录下内存溢出的问题

介绍下后端接口情况:后台整体接口返回的数据结构,嵌套层级比较多,同时最里层的actions字段会存储大数据,有500+的可能性

image.png

因此会出现如下图的溢出情况,导致整个浏览器崩溃了的问题

698a4f94a1b026796424204b53c55fa.png

后续在开始检查代码,单独注释了所有js文件后,html的渲染是正常的,再逐条去注释每个js逻辑,然后就发现了问题:在onMounted里面接收到了从父组件传过来的数据,这个数据里面就有大数据的存在,同时在子组件中用ref的方式去定义一个变量来接收这个大数据,因此就有问题了,大数据赋值给子组件变量后,这个变量又在html中使用

后来在chatgpt中看到一段解释:

在Vue中,使用ref引用存储从后台接收的数据并传递给子组件是一种常见的做法。然而,如果这个数据结构非常复杂,特别是含有多层嵌套和大量的数据,可能会导致页面加载时出现内存溢出的问题。

  1. 大数据量的渲染问题:

    • 如果从后台接收的数据非常庞大,包含大量的嵌套结构和数据项,Vue在渲染这些数据时会占用大量的内存资源。特别是在组件初始化阶段,如果一次性渲染大量数据,可能会导致内存不足或者性能问题。
  2. 递归嵌套的数据结构:

    • 如果数据是递归嵌套的(例如树形结构或者复杂的对象关联),在Vue中对这种数据进行处理和渲染时,可能会增加内存消耗。特别是在使用递归组件或者深层次的数据嵌套时,需要注意内存使用情况。
  3. 事件监听和数据绑定问题:

    • 如果从父组件传递给子组件的数据包含大量的事件监听器或者复杂的数据绑定逻辑,这些可能会占用额外的内存资源。Vue在管理数据和事件时,会为每个组件实例维护一些额外的状态,如果组件数目庞大或者数据结构复杂,可能会影响性能。
  4. 内存泄漏和生命周期管理:

    • 如果在Vue组件中未正确处理数据的生命周期和销毁过程,可能会导致内存泄漏。特别是对于一些需要频繁更新或者变化的数据,如果没有及时解绑事件、清理引用等,可能会造成内存资源的长期占用。

为了解决页面加载时出现内存溢出的问题,可以考虑以下优化策略:

  • 分页加载或者懒加载数据: 如果可能,尽量分批加载数据,而不是一次性加载所有数据。可以考虑使用分页加载技术,根据需要动态加载数据。
  • 优化数据结构和渲染逻辑: 简化数据结构和渲染逻辑,尽量避免深层次嵌套和复杂的数据关联,优化数据传递和组件设计。
  • 合理使用计算属性和虚拟列表: 使用Vue的计算属性优化数据处理逻辑,使用虚拟列表技术优化大量数据的渲染性能。
  • 合理管理组件生命周期和事件监听器: 在Vue组件中,及时销毁不再使用的数据和事件监听器,避免内存泄漏问题。
  • 使用Vue Devtools进行性能监控和分析: 使用Vue Devtools等工具进行性能监控和分析,查看组件的实际内存使用情况和性能瓶颈,进行针对性优化。

最后解决的方式:

将原先const reviewDatas = ref({});定义的变量改为const reviewDatas = reactive({}) 同时将这个对象中需要用到的数据提前定义

let reviewDatas = reactive<any>({
  showNewRound: false,
  tabButtons: {},
  participantList: [],
  jid: "",
  reviewDiscussions: [],
  showFinalReview: false,
  boardShow: false,
  boardAction: false,
  jmMeEaQcFlag: false,
  list: [],
});

父组件在传递给子组件数据的时候最好也分开传递

            <round
                :reviewDatasObj="reviewDatas"
                :data="tabList[index]"
                :tabButtons="reviewDatas.tabButtons"
                :participantList="reviewDatas.participantList"
                :jid="reviewDatas.jid"
                :roundId="props.roundId"
                :reviewDiscussions="reviewDatas.reviewDiscussions"
                :index="activeName"
                @uploadDatas="uploadDatas"
                :isachive="isachive"
                :positionStatus="positionStatus"
                @updateLoading="updateLoading"
                :showNewRound="reviewDatas.showNewRound"
                :showFinalReview="reviewDatas.showFinalReview"
                :boardShow="reviewDatas.boardShow"
                :boardAction="reviewDatas.boardAction"
                :jmMeEaQcFlag="reviewDatas.jmMeEaQcFlag"
                :list="reviewDatas.list"
              ></round>

image.png

这次反正是解决了,记录下,如果大家有好的方法可以指导下。