rrweb icon indicating copy to clipboard operation
rrweb copied to clipboard

perf(snapshot): avoid recreate element `a` every time

Open H4ad opened this issue 1 year ago • 11 comments

Avoid recreating the same element every time, instead, we cache and we just update the element.

Before: 779k ops/s After: 860k ops/s

Benchmark: https://jsbench.me/ktlqztuf95/1

On Chrome: image

On Firefox: image

H4ad avatar Jan 04 '24 23:01 H4ad

🦋 Changeset detected

Latest commit: d21a234f340d7dbd1ffdc7932f77cac6ef268a98

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
rrweb-snapshot Patch
rrweb Patch
rrdom Patch
rrdom-nodejs Patch
rrweb-player Patch
@rrweb/types Patch
@rrweb/web-extension Patch
rrvideo Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Jan 04 '24 23:01 changeset-bot[bot]

~Could you also test the following possibility:~ [edit: this was much slower]

function getHref(doc: Document) {
  // return a href without hash
  const url = new URL(doc.location.href);
  url.hash = ''
  return url.href;
}

~Some more work would need to be done to support the new customHref case so maybe this PR is fine~

eoghanmurray avatar Feb 02 '24 11:02 eoghanmurray

I've a version which should perform just as good without the need for caching in #1434

@H4ad would you like to run benchmarks on that?

eoghanmurray avatar Mar 29 '24 12:03 eoghanmurray

@eoghanmurray Sorry for taking so long to answer, I will run the benchmarks as soon I can and I will bring back the results

H4ad avatar Mar 29 '24 12:03 H4ad

(in case you miss the thread further up)

Could you cherry-pick https://github.com/eoghanmurray/rrweb/commit/615e164fe6bf3f48f5766f283e9e94d723cfc7fa

And also rebase or merge master

eoghanmurray avatar Apr 02 '24 13:04 eoghanmurray

@eoghanmurray Done!

H4ad avatar Apr 02 '24 23:04 H4ad

I've added another review comment as I'd like to be able to recreate the SPA scenario via a test which necessitates the cache bust. I created a test case but was not able to recreate the scenario where the cache bust is needed.

eoghanmurray avatar Apr 05 '24 13:04 eoghanmurray

@eoghanmurray did you submit the review?

H4ad avatar Apr 07 '24 16:04 H4ad

I've added another review comment

This is what I was referring to: https://github.com/rrweb-io/rrweb/pull/1387/files#diff-6434d77e679a3d1e4217dcad03ee6f02551e41dc0b077a06a45020e68e1b4ee3R222

Here is the test I was talking about, which could be cherry-picked in here, but basically it doesn't demonstrate any need for the ./clear-current stuff, so maybe you can enhance the test case? https://github.com/eoghanmurray/rrweb/commit/4d521651eb4c27e96a8c786860d44a386411da34

And here's a refactoring of how to 'clear the cache' so that it only does it if there is an old A element, and if it's value is different to the incoming value: https://github.com/eoghanmurray/rrweb/commit/38e677a29ff23e8e91fc697aa9e01772140c3171

eoghanmurray avatar Apr 11 '24 11:04 eoghanmurray

I propose merging a version of my changes: https://github.com/rrweb-io/rrweb/commit/38e677a29ff23e8e91fc697aa9e01772140c3171

but without the This is needed for SPAs. bit as we don't yet have any evidence that that is necessary.

eoghanmurray avatar Apr 26 '24 13:04 eoghanmurray

You are right, I don't know if it was a bug on Chrome when I tested but the behavior that I described in the comment is not true anymore.

I have updated the code to reflect your changes and I also removed those comments/code about SPA.

Thanks for the patience, I was very lazy on this PR.

H4ad avatar Apr 26 '24 14:04 H4ad

Would you be able to cherry pick https://github.com/eoghanmurray/rrweb/commit/4d521651eb4c27e96a8c786860d44a386411da34 as I think it still has worth in the event of this implementation being changed in future.

(Although 'Maintainers are allowed to edit this pull request' is checked, I'm unable to push to your H4ad origin due to other permissions issues)

eoghanmurray avatar May 02 '24 12:05 eoghanmurray

Actually I'll just create a new PR for that test case

eoghanmurray avatar May 02 '24 12:05 eoghanmurray

@H4ad I found a bug where a blob: style url would be persisted on the cached anchor element and would incorrect return values on subsequent calls to getHref. Fix in #1467

But could you re-review this PR in view of those single page app bugs you previously encountered?

eoghanmurray avatar May 03 '24 11:05 eoghanmurray

Sure, I will try to leave a review as soon as possible.

H4ad avatar May 03 '24 11:05 H4ad

Just to note, using URL.canParse can make #1434 more competitve; only ~20% slower in jsbench:

function absoluteToDocCanParse(doc, attributeValue) {
// todo: do we need check if attributeValue is ''? 
    if (URL && URL.canParse(attributeValue)) {
	return new URL(attributeValue, doc.location.href).href;
    } else {
	const a = doc.createElement('a');
	a.setAttribute('href', attributeValue);
	return a.href;
    }
}

eoghanmurray avatar May 03 '24 14:05 eoghanmurray