-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Timing issue on whether custom theme take effect #3348
Comments
I am beginning to get a sense of what is happening as I now found out where the loading of my theme.html is processed. As a theme file is processed Polymer builds up an object with all the theme properties (ie the "--primary-text-color" type of entries) as keys and the value from the declaration as the value. If a later declaration comes along it overwrites one with the same name that is already set. In paper toolbar it imports at its top level of scope, default-styles.html. If this is processed before my theme file all is well, but if it is processed after my theme file, then its contents overwrite the existing theme value. |
I think you face the same problem I've seen here - PolymerElements/paper-styles#93 The last import defining a var value wins - which makes IMHO quite hard to apply your own theme reliably. |
@IntranetFactory Yes, I've just read that and it absolutely the same thing. As you can see from my analysis, this is not any easy thing to deal with as it appears to depend on the length of time it takes the various theme files to load. I think the only reliable solution will be to have something like theme files defined/imported into head should have priority over those imported into elements. |
@IntranetFactory and @akc42 Could this be easily reproduced by artificially getting the server to serve the theme file very slowly (say after 4 seconds)? |
@mercmobily Not sure which theme file you want to load slowly. If you mean the default theme referenced by paper-toolbar, then yes thats how I discovered the problem. I was running my Polymer App from a first generation raspberry pi and paper toolbar and the default theme file were taking a long time to load compared to my theme file. So much so they arrived after my theme, even though my theme was the very last item in elements/elements.html. If you want to fix the problem and you want to load your own theme file very slowly, yes the might work but you don't know how long. You will then have the wrong theme on display for a while. See my solution in the thread @IntranetFactory references. I wait on dom ready, then inject my theme's html import request into head dynamically. |
No I was only asking because I wanted a clear,-cut way to replicate the issue reliably! |
@mercmobily OK I understand. My server is working exclusively as http2 (this app has a hand crafted nodejs server) now, so parallel loading of files is the norm. With just http or https I am not sure how things would work and I can't obviously see how you can be sure that the requests don't just get queued serially. You can artificially demonstrate the issue by putting your theme file html import immediately after the webcomponents-lite.js import. It gets loaded first and is then overwritten by the later loading default.theme from paper toolbar. But it is only artificial. I believe nginx has http/2 support - and with Chrome Dev tools you can get the browser to load files very slowly by simulating slow links. That might do it. |
So, I think that there's another solution here, and the docs should provide guidance about theming elements. The paper elements have a set of default styles for their themes. Those defaults are defined in separate files so you can override them. To override these defaults, you should import them first.
This ensures that |
@arthurevans Does this work because Even if what I wrote is 100% correct, I do have a (rather big) "BUT" here. This solution would be summarised as: "When defining a theme (where "theme" here means a file that redefines existing custom CSS attributes and mixins in order to redefine variables), you need to first include all files that would possibly define or redefine those attributes in the first place; this will make sure that the initial definition of those variables happens before your subsequent redefinition". While this sounds like a workable solution (if I didn't write anything stupid, which would surprise me), I still feel that it's a lot to ask to somebody who wants to write a theme: they would need to make sure to include any CSS-defining file that would define the values that they want to override. Even accepting this as "the" solution, don't we still have the same problem with importHref? Before I say anything else, can I ask you to do me a big favour, and write out what we can definitely trust in terms of loading stylesheets with
I am most likely asking you to spoon-feed me obvious things -- I apologise for this. I am very new to CSS (before Polymer, I refused to have ever anything to do with styling, and then Material design happened and I am sucked in!) So yes, my questions are probably very basic... sorry about that. |
To your first point, yes, exactly. You'll notice, for example, that every Polymer element includes a link to polymer.html, and any other files they depend on. You don't need to worry about importing stuff twice, the browser takes care of de-duplicating requests to the same path. As for your next point, yes, having the import before the style tag in your theme file should ensure that the default styles are loaded before yours. And the rule for CSS is last definition wins, where two definitions clash. (I have probably used the wrong terminology here, I am no sphinx myself when it comes to CSS.) Note, though, that we're only talking about definitions of custom properties specific to a certain set of components. Not "all CSS everywhere". Although you should probably have Will we have the same problem with importHref? If your theme file imports its dependencies correctly, it doesn't matter if you import it dynamically. Or import a new custom element that imports paper-styles. Because you've already ensured that paper-styles has been loaded before the theme. I'm afraid I can't answer all of your timing questions. Importing it right after webcomponents.js? I'm not sure it'll work at all before Polymer is loaded, and at any rate we know it won't work if you load it after paper-styles.html. So that's clearly a non-starter. I don't know why including it at the end of elements.html would be any different from including it after elements.html. I might guess that it has something to do with the dependency tree of all of the imports in the elements.html file. Since the theme file didn't have any (expressed) dependency on polymer.html or paper-styles, the browser may have been happy to load it while it was waiting for other imports that were blocking on polymer.html. This is not super obvious stuff, by the way, there's a lot of new stuff here (imports, custom properties) as well as all the usual complexities of the web (CSS, how the browser parses a document). |
@arthurevans I am supposed to make things clearer -- for myself and anybody else -- and am failing miserably. Let me try again. What happens in PSKIn HTML standard, CSS rules are meant to be applied in the order they appear on the page (not in the order they are loaded).
Here:
The next part of
Which will actually apply the styles in the style module my-greeting.html:
Timing issuesOK, I am having a problem here. I experimented by artificially slow down (by FIVE seconds!) the delivery of
This is used in
The serving of file looks like this:
The end result is that nothing is rendered till the very last file ( @akc42 , can you please give me some indications on how to reproduce this problem starting from the PSK light (so, no vulcanisation, etc.)? What changes would you need to make to the PSK Light precisely, and what file would need to be slow, in order to reproduce this? I would have thought that adding a theming property ( I tried delaying As far as importHref "issue", I agree that it's annoying, but it's at least something that can be dealt with/documented/fixed/whatever -- whereas timing issues are much more painful. Here, I am trying to establish how to reproduce your timing issue. |
(Note: Please make sure you read my comment on GitHub, since I accidentally clicked on "comment" and edited the most important part of my comment) |
@mercmobily This is a pretty complex timing issue. Note that it's crucial that @akc42 is using HTTP2, which can deliver multiple resources in parallel. By the specs, the browser doesn't block parsing or rendering on HTML imports. It does block when it encounters scripts (scripts need to be executed one at a time), so if it hits a script tag it needs to download that script and execute it before it executes any other scripts. So, if you're downloading resources in parallel, and you hit the javascript for polymer, that might take a while to download. If the theme file is the only thing you're importing that doesn't depend on polymer, and it doesn't include any parser-blocking imports (like another reference to polymer.html)--guess what, it might get downloaded next. And it's small, so it's likely to beat polymer.html/polymer.js in a race. Hope that helps explain what's going on here. |
I should add, that it may well be sufficient to import polymer.html in your theme file -- which you should anyway, since it's using a |
@mercmobily I don't really have a setup for PSK that I can easily test on and I am pretty sure that it is going to rely on Polyserve or Web Component Tester providing a server. The crucial element of demonstrating the problem is http/2. This allows parallel loading of things and that means creating an http2 server for PSK which I don't really have time to do. I've described the experiments I did do above - if you set up an http/2 server and then try and replicate what I did with the PSK as your base, you might be able to. |
@akc42 Are you using https://github.com/molnarg/node-http2 for your server? |
@mercmobily I don't think there's any reason to try to reproduce this. Everything is basically WAI here. As far as I understand the HTML imports spec and browser behavior, this is a natural consequence of the setup. If you want to reproduce this for your personal edification, use an HTTP server and delay the JavaScript file(s). Paper-toolbar is neither here nor there. Getting on a plane shortly so can't say anything more here for the moment, but recommend closing this as WAI. |
@mercmobily yes. |
@arthurevans @azakus This is my last attempt to raise some doubts. If I am full of manure, just close the issue and accept my apologies for dragging on. The main problem comes from the fact that my understanding of the specs is different. As far as I know, "things are parsed and executed in the order they appear".
And here: https://www.w3.org/TR/html-imports/#dfn-import-dependent Also, you wrote:
You say "downloading". Shouldn't downloading time be non-determining, according to the specs? Aren't things processed sequentially as they are encountered in the page? If this is true, why would using HTTP2 (or any timing issue) make any difference? If I have, in
And And the theme is simply: What the specs seem to say, is that first So, my real question is: assuming that load time/HTTP2 shouldn't affect anything and that only order should matter, when would As I said, sorry for dragging on and on, but my brain keeps on raising alarm bells about this, and either I have some basic fundamental information wrong in my little head, or maybe it is worthwhile reproducing and checking... |
This issue is quite old and I am having a lot of trouble trying to get the gist of the root problem. If I understand correctly, the combination of HTML imports with HTTP2 and themes sometimes results in a wrong ordering of applying the styles? It would be great to have a JSBin for this issue so that I can investigate what is going on. Could you post one or shall we close this as working as intended (sometime fixed during Polymer 2)? |
I can't remember the detail of this problem any more, and I don't see it in my app now, so it would be difficult for me to create a JSbin. HTTP2 is only an issue because of the possibility of lots of files coming to the client in parallel, with one requested later arriving first, and if I remember the issue correctly the ordering of when my them file arrived verses when the default polymer elements theme arrives affects which takes precedence. My guess is that it should be closed. |
Hm that sounds more like a HTTP2 issue to me. Fine to close this for now, we can always revisit later if we have a clear reproducing broken example. |
I am have a situation where I have a working application when running on my development machine, where the client code is delivered by an nodejs http/2 server application also running on the development machine.
I have moved the server code (the client is delivered by it, but is still running in a browser on my development machine) to a VERY slow first generation Raspberry pi. Now when I start up the application the paper-toolbar doesn't pick up my theme but has the default colors (I can see from the debugger they are coming from paper-styles/default-theme.html) in it, although the latter parts of the page (where I define the style for a raised action button to be --accent-color) do seem to see my theme.
This caused me to experiment with the positioning of the import of my theme.html file. It was originally in my elements/element.html file after importing the polymer elements that were in the but before importing my own custom elements. I am doing this back on my main development machine.
If the theme is imported just after loading webcomponents-lite.js then NONE of the theme applies. If I import it after I import elements/element.html (but still in the index.html file), then it now appears to work.
Finally I imported it at the very end of the elements/element.html file, and it still worked there on my development machine, BUT still didn't work on the Raspberry PI.
HOWEVER - I was able to notice a significant difference in the timing. On my development machine paper-toolbar.html finished loading first, Whereas on the Raspberry PI, even with loading theme.html as the last item in the elements/element.html file, it still loaded ahead of the paper-toolbar.html file because it was much smaller in side and (I presume) the Raspberry PI was struggling with CPU power reading the much larger file.
I suspect that http/2's multiplexing of multiple streams and the fact that I wasn't vulcanizing anything may be why nobody seems to have raised this before.
So it appears a theme file has to be loaded after any elements which are using it. HOWEVER, I spent some time trying to debug the whole page startup thing, and although it is very difficult to follow, it appeared to me that at within the Polymer({ 'is' : 'paper-toolbar' ...}); call all the style parts in the dom-module template where having their --mixin values replaced by style elements with the actual values from the mixin. I have to conclude that the Object that is this element only has properties with define what it will do dom at some later point in the lifecycle, because clearly the theme.html file has to be loaded later.
At this point I got stuck - as I couldn't find out how where in some code which I could put a breakpoint on processed the just loaded theme.html file. I am resorting to raising the issue here because there is clearly a timing dependency, yet there is no mention of this in developers guide (that I could find).
The text was updated successfully, but these errors were encountered: