FontAwesome SVG + JS with pseudo-elements performance issue on Select2 - font-awesome

I'm actually using the FontAwesome 5 package, using the SVG+JS implementation with the "data-search-pseudo-elements" option.
I'm in a context where I use a "Select2" plug-in to display a <select> element, which is containing nearly 600 options (for a timezone selection). But when I try to open the select to choose an option, it takes a very very long time to open (which doesn't occur when using the CSS framework, or when pseudo-elements are disabled)!
A little look in browser performances panel seems to show that it's the FontAwesome script which is responsible of this, while there is no pseudo-element in the elements generated by Select2.
Is there any way to improve FontAwesome performance, or to avoid its activation for some HTML elements?

As long as you have data-search-pseudo-elements enabled, Font Awesome will scan the DOM when changes are made, looking for any pseudo-elements that represent icons that should be converted into <svg> elements.
Unfortunately, a scenario like you've described is the Achilles heel of this feature. Scanning the DOM for all possible pseudo-elements can be slow when there are many DOM elements. And the Mutation Observer causes re-scans to occur whenever the DOM changes--which is what sounds like is happening when you open that select control.
So it's probably best to avoid SVG/JS with pseudo-elements in a situation like this.
While I would not recommend putting more effort into trying a work around, if you're up against a wall and for some reason have a requirement to continue using SVG/JS and pseudo-elements together like this, then here are two possibilities:
If you don't need the MutationObserver to watch for changes, then you could disable it altogether using the Configuration API. For example, add data-observe-mutations="false" to your <script> tag.
If you do need the MutationObserver to watch for changes elsewhere in the DOM, but not on this select control, then after disabling the MutationObserver on load (using the above), you could kick it off programmatically on a smaller region of the DOM using the dom.watch() API with a observeMutationsRoot parameter that is more narrowly scoped. By default, the MutationObserver, when enabled, scans everything under a root of document.body, but this is a way that you can make it work on a smaller region of the DOM.
If you have a requirement to support pseudo-elements, and especially if you need to support that in a DOM with many elements, and especially especially if the DOM is changing a lot, it's almost certainly going to be best for you to use the CSS/Webfont technology.

Related

Using a listener for a tap inside a dom-if

I have a simple button that I want to trigger something when pressed. I gave the button an id and created a listener for id.tap. This works fine, but when I put my button inside a template[is=dom-if] it stops working. Is this meant to work like this? How do I solve this?
Elements inside a dom-if don't exist yet when the element is created, so they're not accessible using this.$. Either give the element an on-tap attribute, or use Polymer.dom(this.root).querySelector to find the element.
FYI, the documentation recommends against the liberal use of dom-if.
Since it is generally much faster to hide and show elements rather than destroy and recreate them, conditional templates are only useful to save initial creation cost when the elements being stamped are relatively heavyweight and the conditional may rarely (or never) be true in given usages. Otherwise, liberal use of conditional templates can actually add significant runtime performance overhead.
Usinghidden$=condition might be the best solution.

CSS fix or CSS reset for all websites

I have made a small popup window that shows up at the bottom of the page (like a recommendation system). But whenever I embed my script to any of the client's website, it disturbs my CSS. Like the CSS which is on the client's website overshadows my CSS and this causes me to fix my CSS for each client. Is there a fix that I will have to install on my code?
Please help
Thanks
This is due to overlapping CSS properties of client's and your newly developed. I recommend you to inspect element of google chrome's very nice feature. You can individually identify your overlapping properties. If this is too much complex. Like James commented give a new id to your pop-up menu, which will separate your pop-up CSS from all other components on your web page
On of the ways I heard about is Shadow Dom, and in this article it describe it and at the beginning of the article he listed the problem in brief: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/
But there is a fundamental problem that makes widgets built out of
HTML and JavaScript hard to use: The DOM tree inside a widget isn’t
encapsulated from the rest of the page. This lack of encapsulation
means your document stylesheet might accidentally apply to parts
inside the widget; your JavaScript might accidentally modify parts
inside the widget; your IDs might overlap with IDs inside the widget;
and so on.
Else which I did my self long time ago is: to name all your ids, classes with a special names for example 'mywebsite.myclass' this may minimize the issue. and I saw this way is used by many bookmarklets which import html,css and javascript to user opened page.
"All browsers" is a lot of browsers :P
CSS is going to get interesting soon thanks to shadow DOM. You are going to be able to create a web component that is completely isolated, DOM and CSS, from the rest of the document, which is exactly what you want.
Obviously, it's not in place in al browsers (only in Chrome at the time of me writing this). Meanwhile, this is what I would do:
Use shadow DOM components if available
Anyway, manually name-space everything you use (CSS classes, JavaScript, etc)
Try to use custom elements for everything. (that way, there's less risk of your e.g. <h2>s being styled by outer CSSs)
As a last resource, use very specific selectors (look up CSS specificity), and use !important. Just to be clear: never do this routinely!
Most of that stuff will fail for some value of "All browsers". You'll have to compromise somewhere, I guess.
Yes you can reset your div styles.
Something like this:
div.your-popup * {
/* your reset */
}
And try to set !important to styles or put them inline.
In addition create unique class names that no one can override it.
P.S. http://www.cssreset.com/

How to navigate accross shadow DOMs recursively

I want to validate a custom polymer element. To do this, I want in javascript to access all my nested polymer elements to see if they are valids.
I can't find an easy way to do this.
this.querySelectorAll does not find my inputs that are nested in other polymer elements. It seems I can't use "/deep/" in these selectors.
Is there an easy way to do this ? Or do I have to do a recursive javascript methods that will call a querySelectorAll in all elements with shadow roots ?? (I guess performances will get ugly...)
Thanks for your help.
If there is no fast solution, I will probably try the other way around (have my inputs register to the parent)
Answer:
element.querySelectorAll() will find some elements when using /deep/, however, it only goes so far (1 shadow dom level). This would indeed necessitate recursive calls from each ElementNode.
Note:
This type of behavior largely goes against the core tenets of HTML (i.e. that the web page works no matter how well-formed the content is). In other words, all elements are valid no matter their placement.
As an example, I have made a custom element that only renders specific child elements and hides all others. This still keeps in line with the above tenet, as an element's base rendering is controlled by the element/agent, but allows for the developer/designer to customize its presentation aside from the standard presentation.

Optimize CSS Delivery - a suggestion by Google

Google suggests to use very important CSS inline in head and other CSS inside <noscript><link rel="stylesheet" href="small.css"></noscript>.
This raises few questions in my mind:
How to prioritize CSS in two files. Everything for that page looks important. Display, font etc. If I move it to bottom then how it helps page render. Wont it cause repaint, etc?
Is that CSS is required after Document ready event? Got it from here.
How 'CSS can' go inside <noscript></noscript>, which is for script? Will it work when JavaScript is enabled? Is it browsers compatible?
Reference
Based on my reading of the link given in the question:
Choose which CSS declarations are inlined based on eliminating the Flash-of-Unstyled-Content effect. So, ensure that all page elements are the correct size and colour. (Of course, this will be impossible if you use web-fonts.)
Since the CSS which is not inlined is deferrable, you can load it whenever makes sense. Loading it on DOMContentReady, in my opinion, goes against the point of this optimisation: launching new HTTP requests before the document is completely loaded will potentially slow the rest of the page load. Also, see my next point:
The example shows the CSS in a noscript tag as a fallback. Below the example, the page states
The original small.css is loaded after onload of the page.
i.e. using javascript.
If I could add my own personal opinion to this piece:
this optimisation seems especially harmful to code readability: style sheets don't belong in noscript tags and, as pointed out in the comments, it doesn't pass validation.
It will break any potential future enhancements to HTTP (or other protocol) requests, since the network transaction is hard-coded through javascript.
Finally, under what circumstances would you get a performance gain? Perhaps if your page loads a lot of initially-hidden content; however I would hope that the browser itself is able to optimise the page load better than this hack can.
Take this with a grain of salt, however. I would hesitate to say that Google doesn't know what they're doing.
Edit: note on flash-of-unstyled-content (abbreviated FOUC)
Say you a block of text spanning multiple lines, and includes some text with custom styling, say <span class="my-class">. Now, say that your CSS will set .my-class { font-weight:bold }. If that CSS is not part of the inline style sheet, .my-class will suddenly become bold after the deferred loading has finished. The text block may reflow, and might also change size if it requires an extra line.
So, rather than a flash of totally-unstyled content, you have a flash of partly-styled content.
For this reason you should be careful when considering what CSS is deferred. A safe approach would be to only defer CSS which is used to display content which is itself deferred, for example hidden elements which are displayed after user interaction.

Shadow DOM and custom styling

So I've read this article and from what I understand, each native browser widget is actually a combination of basic elements, styling and scripts. This begs the question - if they are consisted of basic building blocks, does that mean that there is a way of customizing them through JavaScript? And I don't mean in the replacement sort of way, as some JavaScript libraries/plugins do - simply by accessing their "Shadow DOM" properties and adding some CSS styles to them, for example. Also, this page has some use cases, but nothing practical.
Anyone ever tried anything like this? Is it possible at all? Downsides?
Thanks.
My main concern would be that the implementations of the shadow DOM would be different between browsers and then you are basically back to needing some sort of library to deal with it. I'm not sure if that is the case, but its worth considering. Also, given that there are so many widget libraries available and that is the standard way of handling most of these issues, is it worth taking on a whole new set of unknown issues instead of just working with known elements?