rrweb
rrweb copied to clipboard
Fix inline link elements bug
In PR #909, an async mechanism for inlining link elements is introduced but it still has a bug and some negative impacts on the replayer side.
The Bug
In the stylesheet-manager.ts, when the link element loaded the styles, the manager emits an incremental mutation event to inline styles. But the mutation's parentId is wrong. https://github.com/rrweb-io/rrweb/blob/abc035fd00972c3ffa1a9cf379b46f53cb74d394/packages/rrweb/src/record/stylesheet-manager.ts#L34
As a result, the event looks like this:
https://github.com/rrweb-io/rrweb/compare/master...fix-inline-link-elements#diff-988864050cbe6d85b4cb140a06ffce65819d8967e071b175f1d27b8a864b5383L176-L189
The parentNode of the link element is itself and it can't be appended to the dom actually.
Negative Impacts
This mechanism makes elements absent in the normal snapshot stage and causes performance issues and many warnings in the console. Here's a diagram to explain this problem.
Changes
I built this PR based on #989 so that it contains all changes of that PR. This PR has to get merged after #989.
I made some changes to the current mechanism. In the snapshot stage, the unloaded Link elements will still get serialized without inline styles. After they are loaded. an incremental mutation of attributes is appended which includes an attribute _cssText. Its value is the inlined CSS styles.
{
source: IncrementalSource.Mutation,
adds: [],
removes: [],
texts: [],
attributes: [
{
id: 9,
attributes: {
_cssText: "body { color: pink; }",
},
},
],
}
This way, the unloaded Link elements can be inlined without causing the above-mentioned side effects. On the replaying side, when the replayer encounters the '_cssText' attribute change and its target is the Link element, the replayer can replace the old un-inlined one with the inlined loaded Link element. This method can make it easy to implement the TODO feature as well. https://github.com/rrweb-io/rrweb/blob/abc035fd00972c3ffa1a9cf379b46f53cb74d394/packages/rrweb/src/record/stylesheet-manager.ts#L19-L24
This PR can also fix #981.
Today I encountered an issue with the replayer also caused by this.
This is the link element on the recorder side.

While this screenshot is the link element on the replayer side.
The element is self-nested in 4 depths.
I rebased the latest master branch and this pull request is ready to get reviewed and merged.