Skip to content

Commit

Permalink
use native setTimeout when zone.js is present
Browse files Browse the repository at this point in the history
  • Loading branch information
mdellanoce committed Nov 20, 2023
1 parent 8aea5b0 commit 6b3a9f4
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/fair-seahorses-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'rrweb': patch
---

Use native setTimeout when zone.js is present
24 changes: 4 additions & 20 deletions packages/rrweb/src/record/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
patch,
StyleSheetMirror,
nowTimestamp,
getZoneSymbol,
nativeSetTimeout,
} from '../utils';
import type { observerParam, MutationBufferParam } from '../types';
import {
Expand Down Expand Up @@ -54,11 +56,6 @@ import { callbackWrapper } from './error-handler';
type WindowWithStoredMutationObserver = IWindow & {
__rrMutationObserver?: MutationObserver;
};
type WindowWithAngularZone = IWindow & {
Zone?: {
__symbol__?: (key: string) => string;
};
};

export const mutationBuffers: MutationBuffer[] = [];

Expand Down Expand Up @@ -93,7 +90,7 @@ export function initMutationObserver(
// see mutation.ts for details
mutationBuffer.init(options);
let mutationObserverCtor =
window.MutationObserver ||
getZoneSymbol<typeof MutationObserver>('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
Expand All @@ -103,19 +100,6 @@ export function initMutationObserver(
* window.__rrMutationObserver = MutationObserver
*/
(window as WindowWithStoredMutationObserver).__rrMutationObserver;
const angularZoneSymbol = (
window as WindowWithAngularZone
)?.Zone?.__symbol__?.('MutationObserver');
if (
angularZoneSymbol &&
(window as unknown as Record<string, typeof MutationObserver>)[
angularZoneSymbol
]
) {
mutationObserverCtor = (
window as unknown as Record<string, typeof MutationObserver>
)[angularZoneSymbol];
}
const observer = new (mutationObserverCtor as new (
callback: MutationCallback,
) => MutationObserver)(
Expand Down Expand Up @@ -1104,7 +1088,7 @@ function initFontObserver({ fontCb, doc }: observerParam): listenerHandler {
'add',
function (original: (font: FontFace) => void) {
return function (this: FontFaceSet, fontFace: FontFace) {
setTimeout(
nativeSetTimeout(
callbackWrapper(() => {
const p = fontMap.get(fontFace);
if (p) {
Expand Down
4 changes: 2 additions & 2 deletions packages/rrweb/src/record/observers/canvas/2d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
IWindow,
listenerHandler,
} from '@rrweb/types';
import { hookSetter, isBlocked, patch } from '../../../utils';
import { hookSetter, isBlocked, patch, nativeSetTimeout } from '../../../utils';
import { serializeArgs } from './serialize-args';

export default function initCanvas2DMutationObserver(
Expand Down Expand Up @@ -44,7 +44,7 @@ export default function initCanvas2DMutationObserver(
if (!isBlocked(this.canvas, blockClass, blockSelector, true)) {
// Using setTimeout as toDataURL can be heavy
// and we'd rather not block the main thread
setTimeout(() => {
nativeSetTimeout(() => {
const recordArgs = serializeArgs(args, win, this);
cb(this.canvas, {
type: CanvasContext['2D'],
Expand Down
4 changes: 2 additions & 2 deletions packages/rrweb/src/record/shadow-dom-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
initScrollObserver,
initAdoptedStyleSheetObserver,
} from './observer';
import { patch, inDom } from '../utils';
import { patch, inDom, nativeSetTimeout } from '../utils';
import type { Mirror } from 'rrweb-snapshot';
import { isNativeShadowDom } from 'rrweb-snapshot';

Expand Down Expand Up @@ -74,7 +74,7 @@ export class ShadowDomManager {
}),
);
// Defer this to avoid adoptedStyleSheet events being created before the full snapshot is created or attachShadow action is recorded.
setTimeout(() => {
nativeSetTimeout(() => {
if (
shadowRoot.adoptedStyleSheets &&
shadowRoot.adoptedStyleSheets.length > 0
Expand Down
28 changes: 25 additions & 3 deletions packages/rrweb/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,28 @@ import type { IMirror, Mirror } from 'rrweb-snapshot';
import { isShadowRoot, IGNORED_NODE, classMatchesRegex } from 'rrweb-snapshot';
import type { RRNode, RRIFrameElement } from 'rrdom';

type WindowWithAngularZone = IWindow & {
Zone?: {
__symbol__?: (key: string) => string;
};
[key: string]: any;
};

export function getZoneSymbol<T>(symbolName: string): T {
const windowWithZone = window as WindowWithAngularZone;
const angularZoneSymbol = windowWithZone?.Zone?.__symbol__?.(symbolName);
if (angularZoneSymbol) {
const zonelessImpl = windowWithZone[angularZoneSymbol] as T;
if (zonelessImpl) {
return zonelessImpl;
}
}

return windowWithZone[symbolName] as T;
}

export const nativeSetTimeout = getZoneSymbol<typeof window.setTimeout>('setTimeout');

export function on(
type: string,
fn: EventListenerOrEventListenerObject,
Expand Down Expand Up @@ -70,7 +92,7 @@ export function throttle<T>(
wait: number,
options: throttleOptions = {},
) {
let timeout: ReturnType<typeof setTimeout> | null = null;
let timeout: number | null = null;
let previous = 0;
return function (...args: T[]) {
const now = Date.now();
Expand All @@ -88,7 +110,7 @@ export function throttle<T>(
previous = now;
func.apply(context, args);
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(() => {
timeout = nativeSetTimeout(() => {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
func.apply(context, args);
Expand All @@ -113,7 +135,7 @@ export function hookSetter<T>(
: {
set(value) {
// put hooked setter into event loop to avoid of set latency
setTimeout(() => {
nativeSetTimeout(() => {
d.set!.call(this, value);
}, 0);
if (original && original.set) {
Expand Down

0 comments on commit 6b3a9f4

Please sign in to comment.