Dart polymer datatable widget

I have created a polymer widget that draws a datatable from a data source url. The code is at https://github.com/dennisfrancis/polymer-dart-datatable-example

Here is the template of the polymer widget

<polymer-element name="dennis-datatable" attributes="dataSrc,jsonArgs,refreshInterval,method">
  <link rel="stylesheet" href="dennis_datatable.css">

      <button id="refresh_button" on-click="{{fetch_data}}">Refresh</button>
      <table class="bordered" id="datatable_table">
          <th template repeat="{{col in cols}}">
        <tr template repeat="{{row in rows}}">

            <td template repeat="{{col in cols}}">
  <script type="application/dart" src="dennis_datatable.dart"></script>

And here is the dart code of the widget that also prints the rendering latency to the Dartium console.

import 'package:polymer/polymer.dart';
import 'dart:async';
import 'dart:html';
import 'dart:convert';

 * A Polymer datatable element.
class DataTable extends PolymerElement {
  @published String dataSrc;
  @published String jsonArgs = "{}";  // Sorting can be done on server side by passing something like sortcol:"colname"
  @published int refreshInterval = 0;
  @published String method = "GET";
  @observable int numrows = 0;
  @observable int numcols = 0;
  @observable List<String> cols;
  @observable List<Map<String,dynamic>> rows;
  ButtonElement refreshButton;
  bool doing_refresh = false;
  Timer fetch_timer;
  String _json_response = "";
  MutationObserver observer;
  DateTime _start_render;
  DateTime _stop_render;

  DataTable.created() : super.created() {
    observer = new MutationObserver(_onMutation);
    observer.observe(getShadowRoot('dennis-datatable').querySelector('#datatable_table'), childList: true, subtree: true);

    refreshButton = this.shadowRoot.querySelector("#refresh_button");
    if (refreshInterval != 0) {
      fetch_timer = new Timer.periodic(new Duration(seconds : refreshInterval), fetch_data);
  void _onMutation(List<MutationRecord> mutations, MutationObserver observer) {
    print('${mutations.length} mutations occurred, the first to ${mutations[0].target}');
  void fetch_data([Timer _]) {

    if (doing_refresh) { return; }
    refreshButton.disabled = true;
    doing_refresh = true;

    if (dataSrc.isEmpty) { return; }

    HttpRequest request = new HttpRequest(); // create a new XHR
    // add an event handler that is called when the request finishes
    request.onReadyStateChange.listen((_) {
      if (request.readyState == HttpRequest.DONE &&
          (request.status == 200 || request.status == 0)) {
        // data saved OK.
        //print(request.responseText); // output the response from the server
        if (_json_response != request.responseText) {  // Avoid json parsing and rendering if same data
          _json_response = request.responseText;
        } else {
          print("No new data");
      doing_refresh = false;
      refreshButton.disabled = false;

    // POST the data to the server
    request.open(method, dataSrc);

    if(method == "POST") {
      request.send(jsonArgs); // perform the async POST
    } else {
  void update_data(String jsonString) {
    Map data = JSON.decode(jsonString);
    numrows = data["numrows"];
    numcols = data["numcols"];
    cols    = data["cols"];
    rows    = data["rows"];
    _start_render = new DateTime.now();
  void _prn_stat() {

    if (_start_render == null) { return; }
    _stop_render = new DateTime.now();
    int diff = _stop_render.millisecondsSinceEpoch - _start_render.millisecondsSinceEpoch;
    print("render time = $diff ms");

The sad part about this widget is that the rendering time is about 20 times worse than what it would take a raw dart program to generate a table with the same data.
See my previous post about rendering latency without using polymer widgets.

I decided to move the table rendering logic from templates to a dart function, until polymer template rendering speed improves. I created a new git branch called min_templates for the same project at github.

Now the rendering latency is competitive to that of the non-polymer dart table benchmark