diff --git a/.changeset/moody-experts-build.md b/.changeset/moody-experts-build.md new file mode 100644 index 0000000000..fb2c399a10 --- /dev/null +++ b/.changeset/moody-experts-build.md @@ -0,0 +1,5 @@ +--- +"@rrweb/record": patch +--- + +Correctly detect when angular has wrapped mutation observer diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index b88d7f452e..1cd267c08f 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -28,6 +28,23 @@ const testableMethods = { const untaintedBasePrototype: Partial = {}; +/* + When angular patches things - particularly the MutationObserver - + they pass the `isNativeFunction` check + That then causes performance issues + because Angular's change detection + doesn't like sharing a mutation observer + Checking for the presence of the Zone object + on global is a good-enough proxy for Angular + to cover most cases + (you can configure zone.js to have a different name + on the global object and should then manually run rrweb + outside the Zone) + */ +export const isAngularZonePresent = (): boolean => { + return !!(globalThis as { Zone?: unknown }).Zone; +}; + export function getUntaintedPrototype( key: T, ): BasePrototypeCache[T] { @@ -63,7 +80,7 @@ export function getUntaintedPrototype( ), ); - if (isUntaintedAccessors && isUntaintedMethods) { + if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) { untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T]; return defaultObj.prototype as BasePrototypeCache[T]; }