Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cc90576
perf(snapshot): optimize code flow of slimDomExcluded
JonasBa Jul 28, 2023
18ca335
perf(snapshot): remove lowerIfExists
JonasBa Jul 28, 2023
ba66b77
perf(snapshot): return early
JonasBa Jul 28, 2023
dc4c7b1
perf(snapshot): test
JonasBa Jul 29, 2023
85b23bf
perf(mutation): shift n^2
JonasBa Jul 29, 2023
bad990b
perf(mutation): improve process
JonasBa Jul 30, 2023
5d59621
fix(mutation): revert regexp exec
JonasBa Aug 1, 2023
58ab15c
fix(prettier): apply formatting
JonasBa Aug 1, 2023
011e0d0
Merge branch 'master' into jb/perf/replay
JonasBa Aug 3, 2023
f6c8738
fix: filter condition
JonasBa Aug 3, 2023
e6bb17e
fix: remove unused import
JonasBa Aug 3, 2023
a927384
fix: lint
JonasBa Aug 3, 2023
23512e6
test: update snapshots
JonasBa Aug 3, 2023
510d82d
revert(genAdds): revert queue implementation
JonasBa Aug 7, 2023
fab0d3d
revert(genAdds): revert snapshot
JonasBa Aug 7, 2023
e188253
feat(benchmark): add blockClass and blockSelector benchmarks
JonasBa Aug 10, 2023
12dc788
Merge branch 'master' into jb/perf/replay
JonasBa Aug 10, 2023
8750f7f
Revert "feat(benchmark): add blockClass and blockSelector benchmarks"
JonasBa Aug 10, 2023
5b05e6b
ref(perf): less recursion and a few minor optimizations
JonasBa Aug 10, 2023
074fdd9
Revert "ref(perf): less recursion and a few minor optimizations"
JonasBa Aug 10, 2023
eab4b25
ref(perf): less recursion
JonasBa Aug 10, 2023
eed46b0
fix(lint): format doc
JonasBa Aug 10, 2023
bc2c8f2
Merge branch 'master' into jb/perf/replay
JonasBa Aug 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge branch 'master' into jb/perf/replay
  • Loading branch information
JonasBa committed Aug 3, 2023
commit 011e0d09f00aa14cb077e48b9ab1df620c5d95db
76 changes: 31 additions & 45 deletions packages/rrweb/src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,8 @@ export default class MutationBuffer {

const texts = [];
for (let i = 0; i < this.texts.length; i++) {
if (!this.mirror.getId(this.texts[i].node)) {
const id = this.mirror.getId(this.texts[i].node);
if (addedIds.has(id) || this.mirror.has(id)) {
continue;
}
texts.push({
Expand All @@ -448,9 +449,28 @@ export default class MutationBuffer {
const attributes = [];
for (let i = 0; i < this.attributes.length; i++) {
const id = this.mirror.getId(this.attributes[i].node);
if (!id && id !== 0) {
if (addedIds.has(id) || this.mirror.has(id)) {
continue;
}

const { attributes: elAttributes } = this.attributes[i];
if (typeof elAttributes.style === 'string') {
const diffAsStr = JSON.stringify(this.attributes[i].styleDiff);
const unchangedAsStr = JSON.stringify(this.attributes[i]._unchangedStyles);
// check if the style diff is actually shorter than the regular string based mutation
// (which was the whole point of #464 'compact style mutation').
if (diffAsStr.length < elAttributes.style.length) {
// also: CSSOM fails badly when var() is present on shorthand properties, so only proceed with
// the compact style mutation if these have all been accounted for
if (
(diffAsStr + unchangedAsStr).split('var(').length ===
elAttributes.style.split('var(').length
) {
elAttributes.style = this.attributes[i].styleDiff;
}
}
}

attributes.push({
id,
attributes: this.attributes[i].attributes,
Expand All @@ -459,9 +479,7 @@ export default class MutationBuffer {

const payload = {
texts,
// text mutation's id was not in the mirror map means the target node has been removed
attributes,
// attribute mutation's id was not in the mirror map means the target node has been removed
removes: this.removes,
adds,
};
Expand Down Expand Up @@ -575,47 +593,7 @@ export default class MutationBuffer {
target.setAttribute('data-rr-is-password', 'true');
}

if (attributeName === 'style') {
let unattachedDoc;
try {
// avoid upsetting original document from a Content Security point of view
unattachedDoc = document.implementation.createHTMLDocument();
} catch (e) {
// fallback to more direct method
unattachedDoc = this.doc;
}
const old = unattachedDoc.createElement('span');
if (m.oldValue) {
old.setAttribute('style', m.oldValue);
}
if (
item.attributes.style === undefined ||
item.attributes.style === null
) {
item.attributes.style = {};
}
const styleObj = item.attributes.style as styleAttributeValue;
for (const pname of Array.from(target.style)) {
const newValue = target.style.getPropertyValue(pname);
const newPriority = target.style.getPropertyPriority(pname);
if (
newValue !== old.style.getPropertyValue(pname) ||
newPriority !== old.style.getPropertyPriority(pname)
) {
if (newPriority === '') {
styleObj[pname] = newValue;
} else {
styleObj[pname] = [newValue, newPriority];
}
}
}
for (const pname of Array.from(old.style)) {
if (target.style.getPropertyValue(pname) === '') {
// "if not set, returns the empty string"
styleObj[pname] = false; // delete
}
}
} else if (!ignoreAttribute(target.tagName, attributeName, value)) {
if (!ignoreAttribute(target.tagName, attributeName, value)) {
// overwrite attribute if the mutations was triggered in same time
item.attributes[attributeName] = transformAttribute(
this.doc,
Expand All @@ -624,6 +602,14 @@ export default class MutationBuffer {
value,
);
if (attributeName === 'style') {
let unattachedDoc;
try {
// avoid upsetting original document from a Content Security point of view
unattachedDoc = document.implementation.createHTMLDocument();
} catch (e) {
// fallback to more direct method
unattachedDoc = this.doc;
}
const old = unattachedDoc.createElement('span');
if (m.oldValue) {
old.setAttribute('style', m.oldValue);
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.