Open henrahmagix opened 4 years ago
That's interesting. I was working lately with a solution that used MutationObserver on the <head>
and triggers a ElementQueries.init
every time a new style
node is found. I think making such an implementation available behind a flag (because MutationObserver costs performance) would solve it for all kind of frameworks.
That sounds great! Some fab explanations of MutationObserver
performance here, for those (like me) who aren't aware: https://stackoverflow.com/questions/31659567/performance-of-mutationobserver-to-detect-nodes-in-entire-dom/39332340
Yeah maybe it's not a performance issue at all anymore and we could just make this available for everyone. Would definitely make working with SPA frameworks very easy and increases compatibility with those (especially Angular). I don't know yet where React/Vue puts their stylesheets for loaded components, but I hope in the head
. For better performance however we should add a new method ElementQueries.parseStyles(stylesNode)
(because init
parses all styles) that parses only style rules from given (newly added) node.
this is working for our Angular application, in the root app.component.ts
export class AppComponent {
constructor(zone: NgZone) {
zone.runOutsideAngular(() => ElementQueries.init());
}
}
About 10% of the time in Safari in an Angular 8 app, there are 0 stylesheets when
DOMContentLoaded
is triggered, which means ElementQueries cannot find any CSS rules to polyfill and basically does not work for us. The above was gleaned from local testing: refreshing and hard-refreshing multiple times until the page loaded and a known container query wasn't applied; debugging the source revealed thatdocument.styleSheets.length
was 0 whenDOMContentLoaded
was triggered, so we must wait a little bit longer to initialise.Basically, if
document.styleSheets.length === 0
wheninit()
is called, this loop does not run, no css rules are detected, and the library doesn't keep checking so future stylesheet additions are not parsed: https://github.com/marcj/css-element-queries/blob/df88b1e9a738206cb0e624da424a19699d14638d/src/ElementQueries.js#L440-L449Our solution is to call
ElementQueries.init()
whendocument.styleSheets.length > 0
. We wait by usingrequestAnimationFrame()
afterDOMContentLoaded
, which unfortunately means we're not getting the nice browser compatibility of this library'sdomLoaded
function.I'm not exactly sure how this library could work around this. In our app, we're fine with looping infinitely with
requestAnimationFrame
until stylesheets become available, because we know there will be some; I'm guessing this library doesn't want to assume that in all cases, i.e. if you added this library to an empty page and it had the above solution by default, it would loop indefinitely rather than just do nothing.Maybe there could be an additional option to use this solution for developers of SPA apps? Perhaps
ElementQueries.listenForMinimumStylesheets(1)
?P.S. I love this library! It's a really smart solution đź’Ž