Performance issue when creating multiple copies of a custom element (ShadowDOM-polyfill)

152 views
Skip to first unread message

Ümit Seren

unread,
May 22, 2014, 7:26:33 AM5/22/14
to polym...@googlegroups.com

I have been working a port of markerclusterer-plus to polymer (see other thread in the mailing list) and so far it works fine.
I tried to compare performance between the original library and the my port and somehow realized that the polymer port with the ShadowDOM polyfill is almost 10 times slower (147ms vs 21ms).
If I activate native ShadowDOM it is nearly as fast as the original library (around 30ms).

I tried to profile it by using the timeline and it seems that most of the time is spent in the boot.js script (Polymer library).

So I decided to do some CPU profiling (see attached profiles and screenshots):

Original library


Polymer with ShadowDOM polyfill


Polymer with native ShadowDOM


The interesting part is the addToClosestCluster_ function. This function is called for each marker (100 markers in total) and the function loops through
all existing clusters to find the nearest. if a cluster is found the marker is added, if it isn’t it will create a new cluster and add the marker to it.

The main difference between the two libraries is that the non-polymer version creates a simple DIV element for the clustericon but in my polymer port I clone a polymer-element which the user can specify during runtime

clusterIcon = document.importNode(this.clusterIconTemplate_,true);

As you can see in the flame chart each document.import call will take around 13ms with most of the time being spent in the ShadowDOM polyfill.
With native ShadowDOM it only takes around 2 ms per import call.

I must say that I am impressed with the native ShadowDOM performance considering that the original library only uses a simple DIV for a ClusterIcon whereas the Polymer port uses an entire polymer-element.

Are there any best-practices regarding stamping/cloning or instantiating (potentially) many polymer-elements ?
Of course I could just use a simple DIV as in the original library but the one of the goals was to allow for custom cluster icons that themselves are polymer-elements. 


Non_polymer.cpuprofile
Polymer.cpuprofile
Polymer_native.cpuprofile

Eric Bidelman

unread,
May 22, 2014, 6:37:49 PM5/22/14
to Ümit Seren, polymer-dev
Two things you could try:

1. For chromestatus.com, the feature list is stamped using <template repeat>. Each panel has a slew of custom elements inside it. To speed up perf, most of the feature panel is hidden until the user clicks the feature open (e.g. using <template if="{{open}}">). That sped up the initial load quite a bit for me under the SD polyfill. 

2. Use one time bindings where it's appropriate.


Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/473806b4-48d4-4b63-9a8d-1e1f9c190c21%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ümit Seren

unread,
May 23, 2014, 3:13:15 AM5/23/14
to polym...@googlegroups.com, Ümit Seren
Hi Eric,

Thanks for the suggestions. 
Do you think that using <template repeat> instead of manually looping and calling importNode would improve performance ? 
Can I use dynamic polymer elements that are specified during runtime by the user together with <template-repeat>?

Usually when I create a CusterIcon I am also going to show it to the user. So I think the conditional expression won't help me here. 
It seems that most time is spent parsing the template and creating the instance. 
How would one time bindings help performance when instantiating a polymer-element ? I thought the bindings are processed asynchronously in the next microtask ? 

But then I can see that some CPU time is also spent in processBindingDirectives_ which is called by shadowFromTemplate. 

Eric Bidelman

unread,
May 25, 2014, 9:43:15 PM5/25/14
to Ümit Seren, polymer-dev
On Fri, May 23, 2014 at 12:13 AM, Ümit Seren <uemit...@gmail.com> wrote:
Hi Eric,

Thanks for the suggestions. 
Do you think that using <template repeat> instead of manually looping and calling importNode would improve performance ? 

I would. It's highly convenient. You should never need to manually importNode. The data binding system is smart and knows to make the minimal amount of DOM changes to render the model state. There's a good discussion of what it does here:


 
Can I use dynamic polymer elements that are specified during runtime by the user together with <template-repeat>?


I'm not sure if that's what you're after though.

Reply all
Reply to author
Forward
0 new messages