ResizeObserver loop limit exceeded报错解决方案

ResizeObserver loop limit exceeded报错解决方案

背景

​ 公司内部搭建了前端监控系统Sentry,我把一些项目接入进去,一周后发现上报数量最多的事件是ResizeObserver loop limit exceeded。这些事件上报得太多,给Sentry服务造成很大压力,于是研究一番准备解决之。

问题原因

  1. element ui中table组件的resize回调代码如下
/* istanbul ignore next */
export const addResizeListener = function(element, fn) {
  if (isServer) return;
  if (!element.__resizeListeners__) {
    element.__resizeListeners__ = [];
    element.__ro__ = new ResizeObserver(resizeHandler);
    element.__ro__.observe(element);
  }
  element.__resizeListeners__.push(fn);
};
  1. 如果在一个动画帧内,ResizeObserver不能处理所有的observations,就会触发这个ResizeObserver loop limit exceeded

解决方案

  1. 阻止table的重绘,例如给所有列都增加width,但是这个方案不好,无法自适应宽度。

    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="date" label="日期" width="180"> </el-table-column>
      <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
      <el-table-column prop="address" label="地址" width="180"> </el-table-column>
      <el-table-column prop="address" label="地址" width="180"> </el-table-column>
      <el-table-column prop="address" label="地址" width="180"> </el-table-column>
    </el-table>
    
  2. resize时,给回调进行节流,使其1帧内最多执行一次。代码如下:

    import Vue from 'vue';
    import ElementUI, { Table } from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    import App from './App.vue';
    // 解决 ElTable 自动宽度高度导致的「ResizeObserver loop limit exceeded」问题
    const fixElTableErr = (table) => {
        const oldResizeListener = table.methods.resizeListener;
        table.methods.resizeListener = function () {
            window.requestAnimationFrame(oldResizeListener.bind(this));
        };
    };
    // 一定要在Vue.use之前执行此函数
    fixElTableErr(Table);
    
    Vue.use(ElementUI);
    
    new Vue({
        el: '#app',
        render: (h) => h(App),
    });
    
    
  3. element ui 在最新的版本中已经使用decounce方法修复了这个问题,源码如下:

    /* istanbul ignore next */
    export const addResizeListener = function(element, fn) {
      if (isServer) return;
      if (!element.__resizeListeners__) {
        element.__resizeListeners__ = [];
        element.__ro__ = new ResizeObserver(debounce(16, resizeHandler));
        element.__ro__.observe(element);
      }
      element.__resizeListeners__.push(fn);
    };
    
  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值