Description
Problem Statement
I use react-draggable for my project. This package allows you to drag and drop elements on the page. However, when I installed Sentry, I encountered very high resource consumption. After debugging Sentry, I realized that MutaionObserver catches all style attribute changes and then sends them to Service Worker. There are so many events that the processor core is clogged up to 100%. In addition, the movement of elements becomes ragged and intermittent.
Solution Brainstorm
While browsing in the debugger I noticed an interesting function options.onMutation(mutations). In the file node_modules/@sentry/react/node_modules/node_modules/@sentry-internal/rrweb/dist/rrweb.js
(I couldn't find the source code, so I attached it as is)
function initMutationObserver(options, rootEl) {
const mutationBuffer = new MutationBuffer();
mutationBuffers.push(mutationBuffer);
mutationBuffer.init(options);
let mutationObserverCtor = window.MutationObserver || /**
* Some websites may disable MutationObserver by removing it from the window object.
* If someone is using rrweb to build a browser extention or things like it, they
* could not change the website's code but can have an opportunity to inject some
* code before the website executing its JS logic.
* Then they can do this to store the native MutationObserver:
* window.__rrMutationObserver = MutationObserver
*/
window.__rrMutationObserver;
const angularZoneSymbol = window?.Zone?.__symbol__?.("MutationObserver");
if (angularZoneSymbol && window[angularZoneSymbol]) {
mutationObserverCtor = window[angularZoneSymbol];
}
const observer = new mutationObserverCtor(
callbackWrapper((mutations) => {
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (options.onMutation && options.onMutation(mutations) === false) {
return;
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mutationBuffer.processMutations.bind(mutationBuffer)(mutations);
})
);
observer.observe(rootEl, {
attributes: true,
attributeOldValue: true,
characterData: true,
characterDataOldValue: true,
childList: true,
subtree: true
});
return observer;
}
It calls the code provided below.
sentry-javascript/packages/replay-internal/src/replay.ts
Lines 1307 to 1337 in 7f3f6f7
Why not make a call, for example, another call to a callback function, which will be specified in options to Sentry.replayIntegration. Where it will be possible to filter out those events that the user considers unnecessary?
Sentry.replayIntegration({
beforeMutationEvent(events: MutationRecord[]): boolean {
// my condition, to exclude some style change events for specified element
return true;
}
}),
Metadata
Metadata
Assignees
Type
Projects
Status