Perf: Apply the latest text mutation only (#885)

* Perf: apply the latest text mutation only

* Find unique text mutations in one iteration
This commit is contained in:
Justin Halsall
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 1c50bdcd44
commit 4f2f739d93
3 changed files with 26 additions and 2 deletions

View File

@@ -52,6 +52,7 @@ import {
getBaseDimension,
hasShadowRoot,
isSerializedIframe,
uniqueTextMutations,
} from '../utils';
import getInjectStyleRules from './styles/inject-style';
import './styles/style.css';
@@ -179,9 +180,10 @@ export class Replayer {
this.fragmentParentMap.forEach((parent, frag) =>
this.restoreRealParent(frag, parent),
);
// apply text needs to happen before virtual style rules gets applied
// as it can overwrite the contents of a stylesheet
for (const d of mutationData.texts) {
for (const d of uniqueTextMutations(mutationData.texts)) {
this.applyText(d, mutationData);
}
@@ -1613,7 +1615,7 @@ export class Replayer {
Object.assign(this.legacy_missingNodeRetryMap, legacy_missingNodeMap);
}
d.texts.forEach((mutation) => {
uniqueTextMutations(d.texts).forEach((mutation) => {
let target = this.mirror.getNode(mutation.id);
if (!target) {
if (d.removes.find((r) => r.id === mutation.id)) {

View File

@@ -587,3 +587,23 @@ export function hasShadowRoot<T extends Node>(
): n is T & { shadowRoot: ShadowRoot } {
return Boolean(((n as unknown) as Element)?.shadowRoot);
}
/**
* Returns the latest mutation in the queue for each node.
* @param {textMutation[]} mutations The text mutations to filter.
* @returns {textMutation[]} The filtered text mutations.
*/
export function uniqueTextMutations(mutations: textMutation[]): textMutation[] {
const idSet = new Set<number>();
const uniqueMutations: textMutation[] = [];
for (let i = mutations.length; i--; ) {
const mutation = mutations[i];
if (!idSet.has(mutation.id)) {
uniqueMutations.push(mutation);
idSet.add(mutation.id);
}
}
return uniqueMutations;
}

View File

@@ -10,6 +10,7 @@ export declare function patch(source: {
export declare function getWindowHeight(): number;
export declare function getWindowWidth(): number;
export declare function isBlocked(node: Node | null, blockClass: blockClass): boolean;
export declare function isSerialized(n: Node, mirror: Mirror): boolean;
export declare function isIgnored(n: Node, mirror: Mirror): boolean;
export declare function isAncestorRemoved(target: Node, mirror: Mirror): boolean;
export declare function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent;
@@ -62,4 +63,5 @@ export declare function getBaseDimension(node: Node, rootIframe: Node): Document
export declare function hasShadowRoot<T extends Node>(n: T): n is T & {
shadowRoot: ShadowRoot;
};
export declare function getUniqueTextMutations(mutations: textMutation[]): textMutation[];
export {};