-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf(rrweb): optimize random shuffled addList #1302
base: master
Are you sure you want to change the base?
Conversation
|
@wfk007 it unfortunately looks like there are some performance impacts for this change in certain situations. I recently encountered a slow mutation with an old version of the jstree library. Here's a plunker that demonstrates the issue. There's 2 rrweb builds in there, one with the "shuffle fix" and one without. Here's the profile for the "without" build: Here's the profile for the "with" build: Looks like this particular mutation spends a lot more time in that Sidenote: by applying a couple more fixes that are in PR limbo, I got the processing time for the mutation in the plunker down to just over 100ms. Some of the proprietary recording solutions out there can handle it in 50ms... |
@mdellanoce I considered that this PR was not the optimal solution, and the implementation was not very elegant, so I changed it to a draft. When I am not busy later, I can also take a look at this case. Thanks for your feedback. |
another possibility for a fix:
Tries a little harder to find nodes that might have a serialized parent/sibling. Fixes the shuffle issue and performs well for the jstree issue as well. Unfortunately, it does slow down the "create 1000 DOM nodes and append into its previous looped node" benchmark. Feels like the worst case just keeps changing depending on the fix. The original "defragment" change in #1300 is the most general purpose I've found so far, but obviously has the downside of slowing down the average case. |
@mdellanoce I know why "without shuffle fix" is faster than "with". The above Dom structure can be created in many ways.
const div1 = document.createElement('div');
div1.setAttribute('id', 'div1')
const div2 = document.createElement('div');
div2.setAttribute('id', 'div2')
div1.append(div2)
document.body.append(div1)
const div1 = document.createElement('div');
div1.setAttribute('id', 'div1')
document.body.append(div1)
const div2 = document.createElement('div');
div2.setAttribute('id', 'div2')
div1.append(div2) These two approach will generate different MutationObserver by browser
[
{
target: body,
addNodes: [div1],
type: "childList"
}
]
[
{
target: body,
addNodes: [div1],
type: "childList"
},
{
target: div1,
addNodes: [div2],
type: "childList"
},
] In order to comprehensively consider the above two cases, when looping The order will directly affect the performance in the emit phase.
What is currently known: We have two thinking directions to optimize this problem:
This is a question worth thinking about! |
@wfk007 I've been (slowly) working at it from this angle. I'm trying to ensure linear time processing for added nodes on both the record and replay sides. I hope to have something to share soon. |
i updated my PR #1300 with another potential solution |
i updated #1300 with a benchmark for the 2nd style of mutation mentioned above |
ref: #1300