ResizeObserver的错误

为什么会存在ResizeObserver错误

ResizeObserver loop completed with undelivered notifications.

ResizeObserver用于监听元素content size和border size的变化。但是元素的变化和监听可能会导致循环触发,例如有元素A,监听元素A尺寸变化后将元素A的宽度加10px,如果没有特殊处理,那么线程将一直被占用无法进行其他任务,因为:A 宽度加10,监听到元素A尺寸变化后,A 宽度加10,监听到元素A尺寸变化后,A 宽度加10...就这么一直下去。

所以浏览器引入了策略,触发ResizeObserver事件后,所有回调会在这一帧绘制到屏幕前执行,在遍历执行所有回调函数时对于触发回调的目标元素和其父元素的ResizeObserver的监听回调会推迟到下一帧执行,同时会在控制台抛出错误ResizeObserver loop completed with undelivered notifications.

也就是说:

  1. A > B 当A宽度增加时,B宽度同步增加同时监听A元素和B元素的变化。那么当A元素变化时监听B元素尺寸变化的回调会同步执行,并且A元素变化的监听函数会推迟到下一帧执行,并且控制台报错,因为有未执行的回调。

  2. Contaienr > A > B 当A宽度增加时,B宽度同步增加同时监听A元素和B元素的变化,Container元素的宽度同样会增加。那么当A元素变化时监听B元素尺寸变化的回调会同步执行,并且A元素和Container元素变化的监听函数会推迟到下一帧执行并且控制台报错,因为有未执行的回调。

怎么避免

  1. 避免循环执行:在回调中判断达到目标值之后就不修改元素尺寸,导致回调意外触发。

  2. 延迟尺寸修改到下一帧:将执行顺序改为,帧1,A元素尺寸变化 -> 帧2,执行A元素尺寸变化的回调 -> 帧3,元素尺寸变化 -> ... 这样一直下去,就不会触发控制台报错,因为监听和触发是分帧进行的。

javascript 复制代码
const resizeObserver = new ResizeObserver((entries) => {
  requestAnimationFrame(() => {
    for (const entry of entries) {
      entry.target.style.width = `${entry.contentBoxSize[0].inlineSize + 10}px`;
    }
  });
});

参考

ResizeObserver

相关推荐
丷丩3 分钟前
MapLibre GL JS第21课:绘制GeoJSON点图标、注记
前端·javascript·gis·mapbox·maplibre gl js
LCG元14 分钟前
现代Web应用高可用架构设计与性能调优实战
前端·wpf
丷丩34 分钟前
MapLibre GL JS第20课:更新GeoJSON多边形
前端·javascript·gis·mapbox·maplibre gl js
swipe38 分钟前
DeepAgents middleware 工程实战:把复杂 Agent 的运行时基建交给可组合中间件
前端·面试·llm
丷丩44 分钟前
MapLibre GL JS第33课:渲染世界副本
javascript·gis·map·mapbox·maplibre gl js
前端环境观察室1 小时前
别让 Agent 浏览器任务无限重试:失败分类、RetryPolicy 与人工复核
前端
bonechips1 小时前
深入理解 JavaScript的历史包袱——变量提升(Hoisting)
javascript·深度学习
喵个咪1 小时前
Headless 后端实践:基于Go的企业级多栈管理系统脚手架
前端·vue.js·react.js
m0_738120721 小时前
渗透测试基础——黑盒测试下的Web漏洞挖掘与利用解析(一)
服务器·前端·网络·安全·php
丷丩2 小时前
MapLibre GL JS第31课:添加实时数据
javascript·gis·map·mapbox·maplibre gl js