Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Ember.Select is slow with many options (~200) #633

Closed
sandstrom opened this Issue Mar 30, 2012 · 9 comments

Comments

Projects
None yet
4 participants
Contributor

sandstrom commented Mar 30, 2012

Ember.Select is fairly slow with many options, say a country select with 199 countries to choose from.

It's slow because 200 views are created, one for every option. This is useful if the underlying collection changes, because changes are reflected. But typically select options are static.

The following code solves the problem, with the drawback of static options. Is this something you would like to include? If so I'll open a pull request.

Also, please let me know if you have any improvement suggestions.

// A static select where options aren't child-views but plain option tags.
// This implementation is currently much faster than Ember.Select on large collections.

(function() {
var set = Ember.set, get = Ember.get, getPath = Ember.getPath;

Ember.Select = Ember.View.extend({

  staticLabels: false,

  render: function(buffer) {

    var labelKey = get(this, "optionLabelPath").replace("content.", "");
    var valueKey = get(this, "optionValuePath").replace("content.", "");

    if (get(this, "staticLabels")) {

      var output = "";
      if (get(this, "prompt")) {
        output += "<option>" + get(this, "prompt") + "</option>";
      }
      output += get(this, "content").map(function(obj){
        return "<option value='"+get(obj, valueKey)+"'>"+get(obj, labelKey)+"</option>";
      }).join("");

      buffer.push(output);

    } else {
      this._super(buffer);
    }
  },

});
})();
Owner

krisselden commented Mar 30, 2012

One problem, you aren't escaping the values.

var escape = Handlebars.Utils.escapeExpression

escape(get(this, "prompt"))
escape(get(this, valueKey))
escape(get(this, labelKey))

Contributor

sandstrom commented Mar 30, 2012

Yes, good point! Thanks

Owner

ebryn commented Mar 30, 2012

I don't think Select itself is the problem. It's likely the EachView/CollectionView that is rendering the options. We've done some work to improve the performance of them.

@sandstrom What version of Ember are you using?

Contributor

sandstrom commented Mar 31, 2012

@ebryn I'm using 0.9.5

Owner

wagenet commented Mar 31, 2012

@sandstrom Now that 0.9.6 is out can you give that a try?

Contributor

sandstrom commented Mar 31, 2012

Only have a few minutes now, but I took a quick look and Ember.Select with 200 options is faster in 0.9.6 (don't have time to benchmark, so I don't know by how much). However, still not the instantaneous feeling the the hack above gives.

But then, generating 200 views isn't something that one does often, select labels seems like an exception.

Owner

krisselden commented Mar 31, 2012

Aside from the lack of escaping, I don't think what you did is a hack. It is just unbound, I do stuff like this as needed in app code, but it not responding to changes is too surprising to be a replacement for the general purpose control.

Contributor

sandstrom commented Mar 31, 2012

Yes, I agree. Maybe re-generating all options if one of them changed (e.g. an @each observer), or just close since the performance improvements in 0.9.6 has mitigated this problem.

Owner

wagenet commented Apr 17, 2012

@sandstrom I will close this for now. We do have some other ideas for performance improvements that are on our radar.

@wagenet wagenet closed this Apr 17, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment