Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

website/application made with polymer components loads extremely slow on IE11

We are considering polymer technology (& the dart language) to develop a public/internet web application / web site. When testing /validating the approach, we encountered a potential show-stopper. The (basic) site is performing rather o.k. on different browsers & platforms, but it is extremely slow on Internet Explorer 11 on Windows 8.1.

The problem does not seem to be related to our specific code, as it seems easy to reproduce the behaviour using, for example, the polymer demo (menu button): https://www.polymer-project.org/components/paper-elements/demo.html#paper-menu-button

On IE11 (11.0.9600.17351), it takes more than 16 seconds to load that page. With the “UI Responsiveness” profiler of IE11, a .diagsession file was created: http://novonov.be/tmp/polymer-paper-menu-button-demo.diagsession At first sight, the problem does not seem to be related to network traffic / number of files to be downloaded. 15.73 seconds are spent in “DOM event (readystatechanged)”. We did not test another version of IE - only IE11.

Is there any solution/workaround available for this issue? Or does this issue makes that a website / web-application created with polymer components will not work with a reasonable performance in IE(11)? This could be a showstopper for public internet websites / web-applications.

like image 577
Benjamin Avatar asked Nov 05 '14 22:11

Benjamin


4 Answers

The vulcanize tool is key to productionizing an app. Polyfill'd browsers like IE11 will be inherently slower than native HTML imports, so it's important to reduce the number of requests and setup work the polyfills have to do.

For example, I was able to take the SPA demo (https://www.polymer-project.org/articles/demos/spa/final.html) from ~20s to ~3.7s, just by running vulcanize: http://www.webpagetest.org/result/141105_7P_178Q/

like image 187
ebidel Avatar answered Nov 04 '22 16:11

ebidel


The solution to the problem was brought up by jakemac53 on https://github.com/Polymer/polymer/issues/891

Ah, so that one took me a bit to figure out but its because of the shadow dom css polyfill running on the large css files being included in each of your elements (specifically bootstrap). Luckily it is pretty easy to disable this polyfill from running (and its not needed for bootstrap). Simply add the "no-shim" attribute to all of your linked stylesheets, so bootstrap for instance should look like:

Otherwise the polyfill has to copy all the contents from the file and apply its transformations, and then stamp the result into an inline stylesheet. When this is done many times on a large stylesheet like bootstrap it really slows things down.

like image 39
Benjamin Avatar answered Nov 04 '22 16:11

Benjamin


It looks like the slowness on this example is caused by the sheer number of elements on the page. In the country selection dropdowns, there are ~240 paper-item elements, and there are 4 of those dropdowns, so total there are ~1000 paper-item elements on the page. Each of these has two custom elements, paper-ripple and core-icon, so now we are up to ~3000 custom elements, not to mention all the other elements. I confirmed that simply commenting out the majority of the countries dramatically improves performance.

In Firefox and IE they are running under the polyfills which magnifies their performance woes, and so that is why you are seeing such slowness in each of those browsers. Performance is definitely something that the Polymer team is actively working on (especially relating to the polyfills), but any time you have this many elements on the page it is going to cause issues in slower browsers.

like image 33
Jake MacDonald Avatar answered Nov 04 '22 15:11

Jake MacDonald


In response to @ebidel s answer. I Dart this means to run pub build from command line instead from DartEditor.
When run from command line mode=release is used by default. DartEditor calls pub build with mode=debug. The release mode does tree-shaking and minification which leads to smaller code. As far as I know the other things vulcanize does for Polymer.js is done by the Dart Polymer transformer.

Some hints

admin_service_repository/admin_service_repository.dart

@observable List serviceDescriptions = toObservable([]);
// instead of
// @observable List serviceDescriptions = [];

so Polymer gets notified about changes even when loading the data returns after Polymer already created the view from the serviceDescriptions list.

for (Map service in services) {
  //String name = service['name'];
  //ServiceDescription sd = new ServiceDescription(name, service['defaultUrl'], service['description'], service['exampleContent']);
  //addService(sd);
  serviceDescriptions.addAll(
      services.map((s) => new ServiceDescription(s['name'], s['defaultUrl'], 
          s['description'], s['exampleContent']))); 
}

creating the list and adding the items to services could be simplified a bit.

admin_service_repository/node_view.dart

  @observable get allChildren {
//    List list = [];
//    for (Node child in node.children.values) {
//      list.add(child);
//    }
//    return list;
    return node.children.values.toList(); 
  }

In lib/invoke_service you create a list of strings and concatenate them in the constructor.
You can create multi-line string literals like

String someString = r'''
 {
   xxxx
 }
''';

I added

- polymer:
    inline_stylesheets:
      lib/bootstrap/css/bootstrap.min.css: false
      lib/bootstrap/css/bootstrap.min.css: false
      lib/css/op.css: false
      lib/font-awesome-4.2.0/css/font-awesome.min.css: false

to the pubspec.yaml to get rid of the warnings after upgrading to Polymer 0.15.xxx.

like image 28
Günter Zöchbauer Avatar answered Nov 04 '22 15:11

Günter Zöchbauer