新建销售计划-页面卡死问题分析

现象

::: danger 页面冻结 运营人员在手抓饼后台新建销售计划时,上架多个商品后,突然出现页面卡死,网页无法响应用户交互

触发了浏览器 页面冻结 ,表现为点击和输入有操作无响应。 :::

可能原因分析

  1. 在页面进行网络请求时,如果存在某个请求阻塞了页面的加载或渲染过程,可能会导致页面冻结

  2. 当页面需要处理大量的数据或复杂的计算时,可能会消耗大量的系统资源,导致页面冻结

  3. 页面中存在大量的 DOM 元素,尤其是多层嵌套或复杂结构的 DOM 元素会增加页面的渲染负担,可能导致页面冻结。

结合代码逻辑看,第3点可能性比较大,页面点击 Add 操作时,在一个微任务内执行了大量 DOM 遍历,并且重绘了页面

itemSub (index) {
  // 当前操作对象添加标记
  this.$refs['modifyGoodsItem'][index].changeIndexCurrent()
  this.$refs['modifyGoodsItem'][index].changeOperateBtn(false)
  // 遍历处理所有数据
  this.reRenderDataList()
},
reRenderDataList () { // [!code focus]
  const that = this // [!code focus]
  const dataList = this.$refs['modifyGoodsItem'].map(li => li.getOperateItem()) // [!code focus]
  this.isShowGoodsForm = false // [!code focus]
  this.$nextTick(() => { // [!code focus]
    that.dataList = dataList.flat(2) // [!code focus]
    that.isShowGoodsForm = true // [!code focus]
  }) // [!code focus]
}, // [!code focus]
judgeAllComponent () {
  let msg = ''
  let sum = 1
  const judgeArr = this.$refs['modifyGoodsItem'].map(li => li.judgeAll())
  for (let i = 0; i < judgeArr.length; i++) {
    const li = judgeArr[i]
    sum *= li.sum
    msg = msg ? msg : li.msg
  }
  // 显示最终提示语
  if (msg) {
    this.$elMsg.error(msg)
  }
  return sum
},

解决方案

::: tip 治标

  1. 运营人员使用 chrome 浏览器( v8 引擎,页面内存利用效率更高)

  2. 将微任务强制改为宏任务 :::

::: tip 治本

  1. 记录 Add 按钮引用,避免重新查找原型链

  2. 代码逻辑调整, 减少 DOM 遍历和页面重绘 :::

Last updated