Skip to content
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

Cannot record web Component css #669

Closed
GoncaloDuarte98 opened this issue Aug 16, 2021 · 9 comments · Fixed by #989
Closed

Cannot record web Component css #669

GoncaloDuarte98 opened this issue Aug 16, 2021 · 9 comments · Fixed by #989

Comments

@GoncaloDuarte98
Copy link

I cannot record the css inside a lit Element web Component. I can see the component but no style which breaks the recording

@Yuyz0112
Copy link
Member

@GoncaloDuarte98 Could you provide an example code for debugging?

@GoncaloDuarte98
Copy link
Author

This is the web component:
image
And this is the recording using rrweb:
image

@GoncaloDuarte98
Copy link
Author

[ { "type": 0, "data": {}, "timestamp": 1629103007609, "delay": -5.300048828125 }, { "type": 1, "data": {}, "timestamp": 1629103007637, "delay": 22.699951171875 }, { "type": 4, "data": { "href": "http://localhost:8000/", "width": 1041, "height": 889 }, "timestamp": 1629103007638, "delay": 23.699951171875 }, { "type": 2, "data": { "node": { "type": 0, "childNodes": [ { "type": 1, "name": "html", "publicId": "", "systemId": "", "id": 2 }, { "type": 2, "tagName": "html", "attributes": { "lang": "en-GB" }, "childNodes": [ { "type": 2, "tagName": "head", "attributes": {}, "childNodes": [ { "type": 3, "textContent": "\n ", "id": 5 }, { "type": 2, "tagName": "meta", "attributes": { "charset": "utf-8" }, "childNodes": [], "id": 6 }, { "type": 3, "textContent": "\n ", "id": 7 }, { "type": 2, "tagName": "style", "attributes": {}, "childNodes": [ { "type": 3, "textContent": "\n body {\n background: #fafafa;\n }\n ", "isStyle": true, "id": 9 } ], "id": 8 }, { "type": 3, "textContent": "\n", "id": 10 }, { "type": 2, "tagName": "link", "attributes": { "rel": "stylesheet", "href": "https://cdn.jsdelivr.net/npm/rrweb@latest/dist/rrweb.min.css" }, "childNodes": [], "id": 11 }, { "type": 3, "textContent": "\n ", "id": 12 }, { "type": 2, "tagName": "script", "attributes": { "src": "https://cdn.jsdelivr.net/npm/rrweb@latest/dist/rrweb.min.js" }, "childNodes": [], "id": 13 }, { "type": 3, "textContent": "\n ", "id": 14 } ], "id": 4 }, { "type": 3, "textContent": "\n\n ", "id": 15 }, { "type": 2, "tagName": "body", "attributes": {}, "childNodes": [ { "type": 3, "textContent": "\n ", "id": 17 }, { "type": 2, "tagName": "div", "attributes": { "id": "demo" }, "childNodes": [], "id": 18 }, { "type": 3, "textContent": "\n ", "id": 19 }, { "type": 2, "tagName": "h1", "attributes": {}, "childNodes": [ { "type": 3, "textContent": "Teste", "id": 21 } ], "id": 20 }, { "type": 3, "textContent": "\n ", "id": 22 }, { "type": 2, "tagName": "my-component", "attributes": {}, "childNodes": [ { "type": 5, "textContent": "", "id": 24, "isShadow": true }, { "type": 3, "textContent": "\n ", "id": 25, "isShadow": true }, { "type": 2, "tagName": "button", "attributes": {}, "childNodes": [ { "type": 5, "textContent": "", "id": 27 }, { "type": 3, "textContent": "Copia", "id": 28 }, { "type": 5, "textContent": "", "id": 29 } ], "id": 26, "isShadow": true }, { "type": 3, "textContent": "\n ", "id": 30, "isShadow": true }, { "type": 2, "tagName": "p", "attributes": { "style": "visibility: hidden" }, "childNodes": [ { "type": 3, "textContent": "\n Copiado!\n ", "id": 32 } ], "id": 31, "isShadow": true }, { "type": 3, "textContent": "\n ", "id": 33, "isShadow": true }, { "type": 5, "textContent": "", "id": 34, "isShadow": true } ], "id": 23, "isShadowHost": true }, { "type": 3, "textContent": "\n ", "id": 35 }, { "type": 2, "tagName": "button", "attributes": { "id": "play" }, "childNodes": [ { "type": 3, "textContent": "Log events", "id": 37 } ], "id": 36 }, { "type": 3, "textContent": "\n ", "id": 38 }, { "type": 2, "tagName": "script", "attributes": {}, "childNodes": [ { "type": 3, "textContent": "SCRIPT_PLACEHOLDER", "id": 40 } ], "id": 39 }, { "type": 3, "textContent": "\n\n ", "id": 41 }, { "type": 2, "tagName": "script", "attributes": { "type": "module", "src": "http://localhost:8000/build/index.js" }, "childNodes": [], "id": 42 }, { "type": 3, "textContent": "\n ", "id": 43 }, { "type": 5, "textContent": " injected by web-dev-server ", "id": 44 }, { "type": 3, "textContent": "\n", "id": 45 }, { "type": 2, "tagName": "script", "attributes": { "type": "module", "src": "http://localhost:8000/__web-dev-server__web-socket.js" }, "childNodes": [], "id": 46 }, { "type": 3, "textContent": "\n\n", "id": 47 } ], "id": 16 } ], "id": 3 } ], "id": 1 }, "initialOffset": { "left": 0, "top": 0 } }, "timestamp": 1629103007642, "delay": 27.699951171875 }, { "type": 3, "data": { "source": 2, "type": 7, "id": 36, "x": 41.726104736328125, "y": 187.15872192382812 }, "timestamp": 1629103011359, "delay": 3744.699951171875 }, { "type": 3, "data": { "source": 2, "type": 9, "id": 36, "x": 41.726104736328125, "y": 187.15872192382812 }, "timestamp": 1629103011464, "delay": 3849.699951171875 }, { "type": 3, "data": { "source": 1, "positions": [ { "x": 42, "y": 181, "id": 36, "timeOffset": 0 } ] }, "timestamp": 1629103011466, "delay": 3851.699951171875 }, { "type": 3, "data": { "source": 2, "type": 1, "id": 36, "x": 42, "y": 181 }, "timestamp": 1629103011466, "delay": 3851.699951171875 }, { "type": 3, "data": { "source": 2, "type": 5, "id": 36 }, "timestamp": 1629103011466, "delay": 3851.699951171875 }, { "type": 3, "data": { "source": 2, "type": 0, "id": 36, "x": 42, "y": 181 }, "timestamp": 1629103011467, "delay": 3852.699951171875 }, { "type": 3, "data": { "source": 2, "type": 2, "id": 36, "x": 42, "y": 181 }, "timestamp": 1629103011467, "delay": 3852.699951171875 }, { "type": 3, "data": { "source": 0, "texts": [], "attributes": [], "removes": [], "adds": [ { "parentId": 16, "nextId": null, "node": { "type": 2, "tagName": "div", "attributes": { "class": "replayer-wrapper" }, "childNodes": [], "id": 48 } }, { "parentId": 48, "nextId": null, "node": { "type": 2, "tagName": "iframe", "attributes": { "sandbox": "allow-same-origin", "scrolling": "no", "style": "display: none; pointer-events: none;" }, "childNodes": [], "id": 49 } }, { "parentId": 48, "nextId": 49, "node": { "type": 2, "tagName": "canvas", "attributes": { "class": "replayer-mouse-tail", "style": "display: inherit;" }, "childNodes": [], "id": 50 } }, { "parentId": 48, "nextId": 50, "node": { "type": 2, "tagName": "div", "attributes": { "class": "replayer-mouse" }, "childNodes": [], "id": 51 } } ] }, "timestamp": 1629103011483 }, { "type": 3, "data": { "source": 0, "texts": [], "attributes": [ { "id": 49, "attributes": { "style": { "display": "inherit" }, "width": "1041", "height": "889" } }, { "id": 50, "attributes": { "width": "1041", "height": "889" } } ], "removes": [], "adds": [] }, "timestamp": 1629103011487 }, { "type": 3, "data": { "source": 0, "adds": [ { "parentId": 49, "nextId": null, "node": { "type": 0, "childNodes": [ { "type": 2, "tagName": "html", "attributes": {}, "childNodes": [ { "type": 2, "tagName": "head", "attributes": {}, "childNodes": [], "rootId": 52, "id": 54 }, { "type": 2, "tagName": "body", "attributes": {}, "childNodes": [], "rootId": 52, "id": 55 } ], "rootId": 52, "id": 53 } ], "id": 52 } } ], "removes": [], "texts": [], "attributes": [], "isAttachIframe": true }, "timestamp": 1629103011488 }, { "type": 3, "data": { "source": 0, "texts": [], "attributes": [], "removes": [], "adds": [ { "parentId": 1, "nextId": 3, "node": { "type": 1, "name": "html", "publicId": "", "systemId": "", "id": 2 } }, { "parentId": 1, "nextId": null, "node": { "type": 2, "tagName": "html", "attributes": { "lang": "en-GB" }, "childNodes": [], "id": 3 } }, { "parentId": 3, "nextId": 15, "node": { "type": 2, "tagName": "head", "attributes": {}, "childNodes": [], "id": 4 } }, { "parentId": 4, "nextId": 6, "node": { "type": 3, "textContent": "\n ", "id": 5 } }, { "parentId": 4, "nextId": 7, "node": { "type": 2, "tagName": "meta", "attributes": { "charset": "utf-8" }, "childNodes": [], "id": 6 } }, { "parentId": 4, "nextId": 8, "node": { "type": 3, "textContent": "\n ", "id": 7 } }, { "parentId": 4, "nextId": 10, "node": { "type": 2, "tagName": "style", "attributes": {}, "childNodes": [], "id": 8 } }, { "parentId": 8, "nextId": null, "node": { "type": 3, "textContent": "\n body {\n background: #fafafa;\n }\n ", "isStyle": true, "id": 9 } }, { "parentId": 4, "nextId": 11, "node": { "type": 3, "textContent": "\n", "id": 10 } }, { "parentId": 4, "nextId": 12, "node": { "type": 2, "tagName": "link", "attributes": { "rel": "stylesheet", "href": "https://cdn.jsdelivr.net/npm/rrweb@latest/dist/rrweb.min.css" }, "childNodes": [], "id": 11 } }, { "parentId": 4, "nextId": 13, "node": { "type": 3, "textContent": "\n ", "id": 12 } }, { "parentId": 4, "nextId": 14, "node": { "type": 2, "tagName": "noscript", "attributes": { "src": "https://cdn.jsdelivr.net/npm/rrweb@latest/dist/rrweb.min.js" }, "childNodes": [], "id": 13 } }, { "parentId": 4, "nextId": null, "node": { "type": 3, "textContent": "\n ", "id": 14 } }, { "parentId": 3, "nextId": 16, "node": { "type": 3, "textContent": "\n\n ", "id": 15 } }, { "parentId": 3, "nextId": null, "node": { "type": 2, "tagName": "body", "attributes": {}, "childNodes": [], "id": 16 } }, { "parentId": 16, "nextId": 18, "node": { "type": 3, "textContent": "\n ", "id": 17 } }, { "parentId": 16, "nextId": 19, "node": { "type": 2, "tagName": "div", "attributes": { "id": "demo" }, "childNodes": [], "id": 18 } }, { "parentId": 16, "nextId": 20, "node": { "type": 3, "textContent": "\n ", "id": 19 } }, { "parentId": 16, "nextId": 22, "node": { "type": 2, "tagName": "h1", "attributes": {}, "childNodes": [], "id": 20 } }, { "parentId": 20, "nextId": null, "node": { "type": 3, "textContent": "Teste", "id": 21 } }, { "parentId": 16, "nextId": 23, "node": { "type": 3, "textContent": "\n ", "id": 22 } }, { "parentId": 16, "nextId": 35, "node": { "type": 2, "tagName": "my-component", "attributes": {}, "childNodes": [], "id": 23 } }, { "parentId": 16, "nextId": 36, "node": { "type": 3, "textContent": "\n ", "id": 35 } }, { "parentId": 16, "nextId": 38, "node": { "type": 2, "tagName": "button", "attributes": { "id": "play" }, "childNodes": [], "id": 36 } }, { "parentId": 36, "nextId": null, "node": { "type": 3, "textContent": "Log events", "id": 37 } }, { "parentId": 16, "nextId": 39, "node": { "type": 3, "textContent": "\n ", "id": 38 } }, { "parentId": 16, "nextId": 41, "node": { "type": 2, "tagName": "noscript", "attributes": {}, "childNodes": [], "id": 39 } }, { "parentId": 39, "nextId": null, "node": { "type": 3, "textContent": "SCRIPT_PLACEHOLDER", "id": 40 } }, { "parentId": 16, "nextId": 42, "node": { "type": 3, "textContent": "\n\n ", "id": 41 } }, { "parentId": 16, "nextId": 43, "node": { "type": 2, "tagName": "noscript", "attributes": { "type": "module", "src": "http://localhost:8000/build/index.js" }, "childNodes": [], "id": 42 } }, { "parentId": 16, "nextId": 44, "node": { "type": 3, "textContent": "\n ", "id": 43 } }, { "parentId": 16, "nextId": 45, "node": { "type": 5, "textContent": " injected by web-dev-server ", "id": 44 } }, { "parentId": 16, "nextId": 46, "node": { "type": 3, "textContent": "\n", "id": 45 } }, { "parentId": 16, "nextId": 47, "node": { "type": 2, "tagName": "noscript", "attributes": { "type": "module", "src": "http://localhost:8000/__web-dev-server__web-socket.js" }, "childNodes": [], "id": 46 } }, { "parentId": 16, "nextId": null, "node": { "type": 3, "textContent": "\n\n", "id": 47 } }, { "parentId": 3, "nextId": 4, "node": { "type": 2, "tagName": "style", "attributes": { "_cssText": ".rr-block { background: rgb(204, 204, 204); }noscript { display: none !important; }html.rrweb-paused * { animation-play-state: paused !important; }" }, "childNodes": [], "id": 56 } } ] }, "timestamp": 1629103011496 }, { "type": 3, "data": { "source": 2, "type": 6, "id": 36 }, "timestamp": 1629103014415 }, { "type": 3, "data": { "source": 0, "texts": [], "attributes": [ { "id": 51, "attributes": { "style": { "left": "41.7261px", "top": "187.159px" }, "class": "replayer-mouse active" } } ], "removes": [], "adds": [] }, "timestamp": 1629103015251 }, { "type": 3, "data": { "source": 0, "texts": [], "attributes": [ { "id": 36, "attributes": { "class": ":hover" } }, { "id": 16, "attributes": { "class": ":hover" } }, { "id": 3, "attributes": { "class": ":hover" } } ], "removes": [], "adds": [] }, "timestamp": 1629103015251 }, { "type": 3, "data": { "source": 0, "texts": [], "attributes": [ { "id": 51, "attributes": { "class": "replayer-mouse active", "style": { "left": "42px", "top": "181px" } } } ], "removes": [], "adds": [] }, "timestamp": 1629103015358 }, { "type": 3, "data": { "source": 0, "texts": [], "attributes": [ { "id": 36, "attributes": { "class": ":hover" } }, { "id": 16, "attributes": { "class": ":hover" } }, { "id": 3, "attributes": { "class": ":hover" } } ], "removes": [], "adds": [] }, "timestamp": 1629103015358 } ]

@Yuyz0112
Copy link
Member

Yuyz0112 commented Oct 1, 2021

@GoncaloDuarte98 Could you provide the source code of this web component?

@GoncaloDuarte98
Copy link
Author

GoncaloDuarte98 commented Oct 4, 2021

@Yuyz0112 you can try these examples lit playground, starter kit and material wc. It doesn't work with any web component using lit

@Yuyz0112
Copy link
Member

Yuyz0112 commented Oct 7, 2021

Proposal: record adoptedStyleSheets

Investigate conclusion

After looking into the demos provided by @GoncaloDuarte98, I found lit is using the Construct Stylesheet to style shadow DOM when it's supported(e.g, in Chrome).

Since the constructed stylesheet is in the DOM tree within link, style, or other DOM nodes, the current recording implementation will not record them.

Inline the adoptedStyleSheets into events

A simple solution is to access the adoptedStyleSheets property via JS API and inline the stylesheet object into a rrweb event, then we can replay it by creating a stylesheet and assign it to the corresponding document's adoptedStyleSheets property.

But looking into the real-world use case of Construct Stylesheet, this way may cause a lot of duplicate inline styles and bump the size of a session.

Construct Stylesheet is created for reusing

In this blog, we can see people used to reuse Construct Stylesheet across shadow DOM.

For example, this demo has the same stylesheet object in every button DOM(every button is a shadow-DOM based web component). If we inline every adoptedStyleSheets, there will be tens of duplicate stylesheets on this page.

And things can be much worse if an application has a big shared stylesheet in every component.

Optimization

A way to optimize this is by adding unique ids to Construct Stylesheet during replay and only inline the content of a stylesheet object once.

When iterating the DOM tree, if a shadow document root has adoptedStyleSheets, it will be recorded as the ids of Construct Stylesheet.

@dbseel
Copy link
Contributor

dbseel commented May 17, 2022

Any update on adding this feature? We have encountered this problem on some sites as well, where the video replay is missing styling due to a constructed stylesheet.

@lele0108
Copy link
Contributor

Ran into this issue with shadow DOM recordings as well, @Yuyz0112's plan looks like a good one. It seems like one of the few remaining shortcomings of the current shadow dom record mechanism. Is there any current plan to implement this? (@Mark-Fenng). Thanks!

@xujiujiu
Copy link
Contributor

xujiujiu commented Jun 5, 2023

However, the compatibility of adoptedStyleSheets is relatively poor. Is there any other solution for low-version browsers (such as ios 12)?
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants